package srdb.migration;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.apache.log4j.Level;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.helpers.OptionConverter;

import srdb.migration.Util.DBInfo;
import srdb.migration.Util.IUIOperation;
import srdb.migration.Util.Util;
import srdb.migration.common.IMTKConnection;
import srdb.migration.common.IMTKFactory;
import srdb.migration.common.MTKConstants;
import srdb.migration.common.MTKData;
import srdb.migration.common.MTKFactory;
import srdb.migration.common.MTKMetaData;
import srdb.migration.common.MTKTransformDDL;
import srdb.migration.dbhandler.enterprisedb.Data;
import srdb.migration.dbhandler.enterprisedb.EnterpriseDBConnection;
import srdb.migration.dbhandler.enterprisedb.MetaData;
import srdb.migration.dbhandler.srdb.SRDBTransformDDL;
import srdb.migration.i18n.ResourceHandler;
import srdb.migration.schema.metadata.Constraint;
import srdb.migration.schema.metadata.ConstraintList;
import srdb.migration.schema.metadata.DBLink;
import srdb.migration.schema.metadata.DBLinkList;
import srdb.migration.schema.metadata.DBObject;
import srdb.migration.schema.metadata.DataType;
import srdb.migration.schema.metadata.DataTypeList;
import srdb.migration.schema.metadata.Domain;
import srdb.migration.schema.metadata.DomainList;
import srdb.migration.schema.metadata.EnumType;
import srdb.migration.schema.metadata.Function;
import srdb.migration.schema.metadata.FunctionList;
import srdb.migration.schema.metadata.Grant;
import srdb.migration.schema.metadata.Group;
import srdb.migration.schema.metadata.GroupList;
import srdb.migration.schema.metadata.Index;
import srdb.migration.schema.metadata.IndexList;
import srdb.migration.schema.metadata.ObjectType;
import srdb.migration.schema.metadata.ObjectTypeList;
import srdb.migration.schema.metadata.Package;
import srdb.migration.schema.metadata.PackageList;
import srdb.migration.schema.metadata.Procedure;
import srdb.migration.schema.metadata.ProcedureList;
import srdb.migration.schema.metadata.Role;
import srdb.migration.schema.metadata.Rule;
import srdb.migration.schema.metadata.RuleList;
import srdb.migration.schema.metadata.Sequence;
import srdb.migration.schema.metadata.SequenceList;
import srdb.migration.schema.metadata.Synonym;
import srdb.migration.schema.metadata.SynonymList;
import srdb.migration.schema.metadata.Table;
import srdb.migration.schema.metadata.TableList;
import srdb.migration.schema.metadata.Trigger;
import srdb.migration.schema.metadata.TriggerList;
import srdb.migration.schema.metadata.User;
import srdb.migration.schema.metadata.View;
import srdb.migration.schema.metadata.ViewList;

import com.edb.commons.db.DBUtils;

public class MigrationToolkit {
    private static MigrationToolkit mtkInstance = null;

    public static boolean VERBOSE = true;
    //    public static final String APP_VERSION = "SRDB Migration Toolkit (Build 1.0)";
//    public static final String OPT_HELP = "help";
//    public static final String OPT_VERSION = "version";
//    public static final String OPT_SCHEMA_ONLY = "schemaOnly";
//    public static final String OPT_DATA_ONLY = "dataOnly";
//    public static final String OPT_CONSTRAINTS = "constraints";
//    public static final String OPT_INDEXES = "indexes";
//    public static final String OPT_TRIGGERS = "triggers";
//    public static final String OPT_ALL_TABLES = "allTables";
//    public static final String OPT_ALL_SEQUENCES = "allSequences";
//    public static final String OPT_ALL_FUNCS = "allFuncs";
//    public static final String OPT_ALL_PROCS = "allProcs";
//    public static final String OPT_ALL_PACKAGES = "allPackages";
//    public static final String OPT_ALL_VIEWS = "allViews";
//    public static final String OPT_ALL_SYNONYMS = "allSynonyms";
//    public static final String OPT_ALL_PUBLIC_SYNONYMS = "allPublicSynonyms";
//    public static final String OPT_ALL_PRIVATE_SYNONYMS = "allPrivateSynonyms";
//    public static final String OPT_ALL_SCHEMAS = "allSchemas";
//    public static final String OPT_ALL_DBLINKS = "allDBLinks";
//    public static final String OPT_ALL_RULES = "allRules";
//    public static final String OPT_ALL_GROUPS = "allGroups";
//    public static final String OPT_ALL_DOMAINS = "allDomains";
//    public static final String OPT_OBJECTTYPES = "objecttypes";
//    public static final String OPT_VACUUM_ANALYZE = "vacuumAnalyze";
//    public static final String OPT_ANALYZE = "analyze";
//    public static final String OPT_EXIT_ON_ERROR = "exitOnError";
//    public static final String OPT_DEFAULT_DATETIME = "defaultDateTime";
    private static SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat(
            "yyyy-MM-dd_HH:mm:ss");
    private static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
            "yyyy-MM-dd");
    private static String defaultDateTime = null;
    //    public static final String OPT_FETCH_SIZE = "fetchSize";
    public static int fetchSize = 0;
    //    public static final String OPT_BATCH_SIZE = "batchSize";
//    public static final String OPT_CP_BATCH_SIZE = "cpBatchSize";
//    public static final String OPT_LOB_BATCH_SIZE = "lobBatchSize";
//    public static final String OPT_TARGET_SCHEMA = "targetSchema";
//    public static final String OPT_VERBOSE = "verbose";
//    public static final String OPT_DROP_SCHEMA = "dropSchema";
//    public static final String OPT_TABLES = "tables";
//    public static final String OPT_VIEWS = "views";
//    public static final String OPT_SEQUENCES = "sequences";
//    public static final String OPT_PROCS = "procs";
//    public static final String OPT_FUNCS = "funcs";
//    public static final String OPT_PACKAGES = "packages";
//    public static final String OPT_SYNONYMS = "synonyms";
//    public static final String OPT_RULES = "rules";
//    public static final String OPT_GROUPS = "groups";
//    public static final String OPT_DOMAINS = "domains";
//    public static final String OPT_PROP = "prop";
//    public static final String OPT_EDB_HOST = "edbhost";
//    public static final String OPT_EDB_USER = "edbuser";
//    public static final String OPT_EDB_PASS = "edbpass";
//    public static final String OPT_ORA_HOST = "orahost";
//    public static final String OPT_ORA_USER = "orauser";
//    public static final String OPT_ORA_PASS = "orapass";
//    public static final String OPT_SRC_DB_URL = "srcdburl";
//    public static final String OPT_SRC_USER = "srcuser";
//    public static final String OPT_SRC_PASS = "srcpass";
//    public static final String OPT_TARGET_DB_URL = "targetdburl";
//    public static final String OPT_TARGET_USER = "targetuser";
//    public static final String OPT_TARGET_PASS = "targetpass";
//    public static final String OPT_TRUNC_BEFORE_LOAD = "truncLoad";
//    public static final String OPT_SAFE_MODE = "safeMode";
//    public static final String OPT_SINGLE_DATA_FILE = "singleDataFile";
//    public static final String OPT_COPY_DELIMITER = "copyDelimiter";
//    public static final String OPT_ESCAPE_TAB_DELIMITER = "escapeTabDelimiter";
//    public static final String OPT_FILTER_PROP_FILE = "filterProp";
//    public static final String OPT_COLUMNS_FILTER_PROP_FILE = "columnsFilterProp";
//    public static final String OPT_GEN_STATS = "genStats";
//    public static final String OPT_STATS_FILE = "statsFile";
//    public static final String OPT_ORA_TX_LEVEL_SERIALIZABLE = "oraTxLevelSerializable";
//    public static final String OPT_IMPORT_VIEW_AS_TABLE = "importViewAsTable";
//    public static final String OPT_IMPORT_PARTTION_AS_TABLE = "importPartitionAsTable";
//    public static final String OPT_SOURCE_DB_TYPE = "sourceDBType";
//    public static final String OPT_TARGET_DB_TYPE = "targetDBType";
//    public static final String OPT_SKIP_FK_CONST = "skipFKConst";
//    public static final String OPT_SKIP_CK_CONST = "skipCKConst";
//    public static final String OPT_IGNORE_CHECK_CONST_FILTER = "ignoreCheckConstFilter";
//    public static final String OPT_SKIP_COL_DEFAULT_CLAUSE = "skipColDefaultClause";
//    public static final String OPT_OFFLINE_MIGRATION = "offlineMigration";
//    public static final String OPT_DBLINKORA = "copyViaDBLinkOra";
//    public static final String OPT_ALL_ROLES_USERS = "allUsers";
//    public static final String OPT_ROLES_USERS = "Users";
//    public static final String OPT_REPLACE_NULL_CHAR = "replaceNullChar";
//    public static final String OPT_FAST_COPY = "fastCopy";
//    public static final String OPT_CUSTOM_COL_TYPE_MAPPING = "customColTypeMapping";
//    public static final String OPT_CUSTOM_COL_TYPE_MAPPING_FILE = "customColTypeMappingFile";
//    public static final String OPT_LOG_DIR = "logDir";
//    public static final String OPT_NZOPTIONS = "nzOptions";
//    public static final String OPT_CHECK_FUNC_BODIES = "checkFunctionBodies";
//    public static final String OPT_RETRY_COUNT = "retryCount";
    private static int retryCount = 2;
    //    public static final String OPT_DATA_LOAD_THREAD_COUNT = "loaderCount";
    private static int dataLoadThreadCount = 10;
    //    public static final String OPT_ENABLE_CONST_BEFORE_DATALOAD = "enableConstBeforeDataLoad";
//    public static final String OPT_USE_ORA_PARTITION_SYNTAX = "useOraPartitionSyntax";
//    public static final String OPT_REPLICATION_MODE = "replicationMode";
//    public static final String RREP_STATS_PROP_FILE = "snapshot_stats.properties";
//    public static final String RREP_STATS_PROP_START_TIME = "START_TIME";
//    public static final String RREP_STATS_PROP_END_TIME = "END_TIME";
//    public static final String RREP_STATS_PROP_DURATION = "DURATION";
//    public static final String RREP_STATS_PROP_STATUS = "STATUS";
//    public static final String RREP_STATS_PROP_ROW_COUNT = "ROW_COUNT";
//    public static final String RREP_STATS_PROP_ERROR_MESSAGE = "ERROR_MESSAGE";
//    public static final String RREP_STATUS_SUCCESS = "S";
//    public static final String RREP_STATUS_FAILED = "F";
//    public static final String RREP_STATUS_WARNING = "W";
    private static String[] rbParameters = new String[0];

    private static String logFile = null;
    //    private String propFile = null;
    private String srcDBURL = null;
    private String srcDBUser = null;

    private String srcDBPassword = "";

    private String targetDBURL = null;
    private String targetDBUser = null;

    private String targetDBPassword = "";

    protected String sourceSchema = null;

    protected String targetSchema = null;

    private String[] tableNames = null;
    private String[] viewNames = null;
    private String[] procNames = null;
    private String[] funcNames = null;
    private String[] packageNames = null;
    private String[] sequenceNames = null;
    private String[] synonymNames = null;
    private String[] userNames = null;
    private String[] ruleNames = null;
    private String[] groupNames = null;
    private String[] domainNames = null;

    private static Hashtable<String, String> sourceToTargetMappings = null;
    private boolean dataOnlyMode = false;
    private boolean schemaOnlyMode = false;
    private boolean parseOnlyMode = false;

    private boolean useOraPartitionSyntax = true;

    private char copyDelimiter = '\t';
    private boolean escapeTabDelimiter = true;
    protected static int batchSize = 5000;
    protected static int cpBatchSize;
    protected static int lobBatchSize = 1;
    private static Hashtable nzOptions = new Hashtable();

    private IMTKConnection srcConn = null;
    private IMTKConnection targetConn = null;
    private MTKMetaData sourceMD = null;
    private MTKMetaData targetMD = null;
    protected MTKTransformDDL tddl = null;
    private static volatile int failureCount = 0;

    private static int fatalErrorCount = 0;
    private Properties filterProp = null;
    private Properties columnsFilterProp = null;
    protected boolean flagGenStats = false;
    private String statsFileName = "snapshot_stats.properties";
    private boolean flagOraTxLevelSerializable = false;
    protected Properties propRepStats = null;
    private boolean flagVacuumAnalyze = false;
    private boolean flagCheckFunctionBodies = true;
    private boolean flagExitOnError = false;
    private boolean flagImportViewAsTable = false;
    private boolean importAllUsers = false;
    protected boolean isfirstSchemaMigrated = false;
    protected boolean enableConstBeforeDataLoad = false;
    private static boolean importPartitionAsTable = false;
    private static ArrayList<String> partitionTableList = null;

    private static String lastErrorMessage = null;

    private MTKConstants.DATABASE_TYPE sourceDBType = MTKConstants.DATABASE_TYPE.ORACLE;
    private MTKConstants.DATABASE_TYPE targetDBType = MTKConstants.DATABASE_TYPE.SRDB;
    protected IMTKFactory mtkFactory = null;
    private boolean flagAnalyze = false;
    private boolean flagSkipFKConst = false;
    private boolean flagSkipCKConst = false;
    private boolean flagSkipPKConst = false;

    private String replicationMode = "S";

    private static boolean flagIgnoreCheckConstFilter = false;

    private boolean isDBLinkOra = false;

    private boolean isDBLinkOraModuleLoaded = false;

    private boolean offlineMigration = false;
    private static String offlineMigrationPath;
    private static String dblinkPasswords = null;

    private boolean flagFastCopy = false;

    private Map<String, String> customColTypeMapping = null;

    private boolean flagUserSpecifiedTargetSchemaName = false;
    private static boolean skipColDefaultClause = false;
    private static boolean replaceNullChar = false;
    private boolean useSingleDataFile = false;
    private static char nullReplacementChar = ' ';

    /**
     * 客户端迁移进度辅助变量
     */
    private static int tableNum = 0; //源数据库表数目
    private static int migratedTables = 0; //已迁移表数目
    private static boolean migrateTableFlag = false; //是否已经执行迁移操作
    private static int indexNum = 0; //源数据库索引数目
    private static int migratedIndexes = 0; //已迁移索引数目
    private static boolean migrateIndexFlag = false; //是否已经执行迁移操作
    private static int constraintsNum = 0; //源数据库约束数目
    private static int migratedConstraints = 0; //已迁移约束数目
    private static boolean migrateConstraintsFlag = false; //是否已经执行迁移操作
    private static int viewNum = 0; //源数据库视图数目
    private static int migratedViews = 0; //已迁移视图数目
    private static boolean migrateViewFlag = false; //是否已经执行迁移操作
    private static boolean migrateFlag = false; //是否已经完成迁移操作
    private static IUIOperation iuiOperation;

    private final MigrationSummary summary = new MigrationSummary();

    public String[] getUserNames() {
        return this.userNames;
    }

    public boolean getUseOraPartitionSyntax() {
        return this.useOraPartitionSyntax;
    }

    public void setUserNames(String[] userNames) {
        this.userNames = userNames;
    }

    public static MigrationToolkit getInstance() {
        if (mtkInstance == null) {
            mtkInstance = new MigrationToolkit();
        }

        return mtkInstance;
    }

    public boolean isImportAllUsers() {
        return this.importAllUsers;
    }

    public void setImportAllUsers(boolean importAllUsers) {
        this.importAllUsers = importAllUsers;
    }

    public static boolean isFlagIgnoreCheckConstFilter() {
        return flagIgnoreCheckConstFilter;
    }

    public boolean isIsDBLinkOra() {
        return this.isDBLinkOra;
    }

    public void setIsDBLinkOra(boolean isDBLinkOra) {
        this.isDBLinkOra = isDBLinkOra;
    }

    private static void configureLogging(String logDir) {
        Properties p = new Properties();
        try {
            // p.load(new FileInputStream("conf/log4j.properties"));
            InputStream in = new Object().getClass().getResourceAsStream(
                    "/srdb/migration/logging/log4j.properties");
            if (in != null) {
                p.load(in);
            } else {
//                throw new Exception("migrationtoolkit 363");
                p.put("log4j.rootLogger", "ALL, OUTPUT, ERR");
                p.put("log4j.appender.OUTPUT", "srdb.migration.logging.OutAppender");
                p.put("log4j.appender.OUTPUT.threshold", "INFO");
                p.put("log4j.appender.OUTPUT.Target", "System.out");
                p.put("log4j.appender.OUTPUT.ImmediateFlush", "true");
                p.put("log4j.appender.OUTPUT.layout",
                        "org.apache.log4j.PatternLayout");
                p.put("log4j.appender.OUTPUT.layout.ConversionPattern", "%m%n");

                p.put("log4j.appender.ERR", "org.apache.log4j.RollingFileAppender");
                p.put("log4j.appender.ERR.File", "logs");
                p.put("log4j.appender.ERR.MaxFileSize", "100KB");
                p.put("log4j.appender.ERR.MaxBackupIndex", "40");
                p.put("log4j.appender.ERR.ImmediateFlush", "true");
                p.put("log4j.appender.ERR.threshold", "ALL");
                p.put("log4j.appender.ERR.layout", "org.apache.log4j.PatternLayout");
                p.put("log4j.appender.ERR.layout.ConversionPattern", "%m%n");
            }
//            p.load();
        } catch (Exception ex) {
            ex.printStackTrace();
            p.put("log4j.rootLogger", "ALL, OUTPUT, ERR");
            p.put("log4j.appender.OUTPUT", "srdb.migration.logging.OutAppender");
            p.put("log4j.appender.OUTPUT.threshold", "INFO");
            p.put("log4j.appender.OUTPUT.Target", "System.out");
            p.put("log4j.appender.OUTPUT.ImmediateFlush", "true");
            p.put("log4j.appender.OUTPUT.layout",
                    "org.apache.log4j.PatternLayout");
            p.put("log4j.appender.OUTPUT.layout.ConversionPattern", "%m%n");

            p.put("log4j.appender.ERR", "org.apache.log4j.RollingFileAppender");
            p.put("log4j.appender.ERR.File", "logs");
            p.put("log4j.appender.ERR.MaxFileSize", "100KB");
            p.put("log4j.appender.ERR.MaxBackupIndex", "40");
            p.put("log4j.appender.ERR.ImmediateFlush", "true");
            p.put("log4j.appender.ERR.threshold", "ALL");
            p.put("log4j.appender.ERR.layout", "org.apache.log4j.PatternLayout");
            p.put("log4j.appender.ERR.layout.ConversionPattern", "%m%n");
        }
        if (logDir == null) {
            logDir = OptionConverter.findAndSubst("log4j.appender.ERR.File", p);
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
        String logFileName = "mtk_" + sdf.format(new Date()) + ".log";
        if (logDir != null) {
            try {
                File file = new File(logDir);
                if ((file.exists()) && (file.isDirectory())) {
                    p.setProperty("log4j.appender.ERR.File",
                            file.getCanonicalPath() + File.separator
                                    + logFileName);
                } else if (file.exists()) {
                    p.setProperty("log4j.appender.ERR.File",
                            file.getCanonicalPath());
                } else if (file.mkdirs())
                    p.setProperty("log4j.appender.ERR.File",
                            file.getCanonicalPath() + File.separator
                                    + logFileName);
                else
                    throw new IOException(ResourceHandler.getValue(
                            "ERR_LOG_PATH_CREATION", new String[]{logDir}));
            } catch (Exception e) {
                p.remove("log4j.appender.ERR.File");
                System.out.println("WARNING: Unable to set the logDir.");
                System.out.println("Reason: " + e.getMessage());
            }
        }

        PropertyConfigurator.configure(p);
        try {
            if ((p.getProperty("log4j.appender.ERR.File") != null)
                    && (p.getProperty("log4j.appender.ERR.File").length() > 0))
                logFile = new File(p.getProperty("log4j.appender.ERR.File"))
                        .getParent();
        } catch (Exception e) {
            logFile = null;
        }
    }

    public static void main(String[] args) {
        if ((args == null) || (args.length == 0)) {
            configureLogging(null);
            usage();
            return;
        }

        String sourceSchema = null;
        String propFile = null;

        boolean copyTableData = true;
        boolean copyTableDDL = true;
        boolean importTables = true;
        boolean importConstraints = true;
        boolean importIndexes = true;
        boolean importTriggers = true;
        boolean importViews = true;
        boolean importSequences = true;
        boolean importProcs = true;
        boolean importFuncs = true;
        boolean importSynonyms = true;
        boolean importPublicSynonyms = false;
        boolean importPrivateSynonyms = false;
        boolean importPackages = true;
        boolean importObjectTypes = true;
        boolean importRules = false;
        boolean importGroups = false;
        boolean importDomains = false;

        boolean importDefaultUser = true;
        boolean dropSchema = false;
        boolean truncBeforeLoad = false;
        boolean safeMode = false;
        boolean importDBLinks = false;
        failureCount = 0;
        fatalErrorCount = 0;
        lastErrorMessage = null;
        propFile = System.getProperty("prop");
        System.out.println("=====  "+propFile);

        mtkInstance = null;
        MigrationToolkit mtk = getInstance();
        nzOptions.clear();
        mtk.resetSummary();
        try {
            CLParser clParser = new CLParser();

            if (!clParser.parseArgs(args)) {
                System.out.println("");
                System.out.println(ResourceHandler.getValue(
                        "WRN_INVALID_COMMAND_LINE_ARG", null));
                return;
            }

            System.out.println("***********clparser:" + clParser);

            String srcSchema = "";
            boolean hasUser = false;
            boolean multipleSchemas = false;

            if (!clParser.hasOption("allSchemas")) {
                if (args.length >= 2) {
                    String secondLastOption = args[(args.length - 2)];
                    if (secondLastOption.equalsIgnoreCase("-Users")) {
                        hasUser = true;
                    } else if ((isKeyValueOption(secondLastOption.substring(1,
                            secondLastOption.length())))
                            && (!secondLastOption
                            .equalsIgnoreCase("-allDBLinks"))
                            && (!secondLastOption
                            .equalsIgnoreCase("-importPartitionAsTable"))
                            && (!secondLastOption
                            .equalsIgnoreCase("-offlineMigration"))) {
                        System.out.println(ResourceHandler.getValue(
                                "WRN_INVALID_COMMAND_LINE_ARG", null));
                        return;
                    }

                }

                if (!hasUser) {
                    srcSchema = args[(args.length - 1)];
                }

            } else {
                if (!args[(args.length - 1)].equalsIgnoreCase("-allSchemas")) {
                    logMessageToSystemOut(ResourceHandler.getValue(
                            "ERR_ALL_SCHEMA_LAST", null));
                    return;
                }
                multipleSchemas = true;
            }

            String[] schemaList = null;
            if ((!clParser.hasOption("allSchemas"))
                    && (!srcSchema.startsWith("-")) && (!srcSchema.equals(""))) {
                schemaList = DBUtils.split(srcSchema, ',', '"');
                multipleSchemas = schemaList.length > 1;
            }

            String[] targetSchemaList = null;
            if (clParser.hasOption("targetSchema")) {
                String targetSchema = clParser.getOption("targetSchema");

                targetSchemaList = DBUtils.split(targetSchema, ',', '"');
            }

            if (!validateOptions(clParser, multipleSchemas)) {
                return;
            }
            if (clParser.hasOption("logDir"))
                configureLogging(clParser.getOption("logDir"));
            else {
                configureLogging(null);
            }
            if ((clParser.hasOption("verbose"))
                    && (clParser.getOption("verbose").equalsIgnoreCase("off"))) {
                VERBOSE = false;
            }

            if (clParser.hasOption("help")) {
                usage();
                return;
            }
            if (clParser.hasOption("version")) {
                Utility.getLogger().info("SRDB Migration Toolkit (Build 46)");
                return;
            }
            if (clParser.hasOption("genStats")) {
                mtk.setGenStats(true);
                mtk.initRepStats();
            }

            if (clParser.hasOption("statsFile")) {
                mtk.setStatsFileName(clParser.getOption("statsFile"));
            }

            if ((!clParser.hasOption("allUsers"))
                    && ((srcSchema.startsWith("--")) || (srcSchema
                    .startsWith("-")))) {
                System.out.println("");
                System.out.println(ResourceHandler.getValue(
                        "WRN_INVALID_COMMAND_LINE_ARG", null));
                return;
            }
            mtk.schemaOnlyMode = clParser.hasOption("schemaOnly");
            mtk.dataOnlyMode = clParser.hasOption("dataOnly");
            mtk.parseOnlyMode = clParser.hasOption("parseOnly");

            truncBeforeLoad = clParser.hasOption("truncLoad");
            safeMode = clParser.hasOption("safeMode");
            mtk.useSingleDataFile = clParser.hasOption("singleDataFile");

            if (clParser.hasOption("sourceDBType")) {
                mtk.setSourceDBType(clParser.getOption("sourceDBType"));
            }

            if (clParser.hasOption("replicationMode")) {
                mtk.setReplicationMode(clParser.getOption("replicationMode"));
            }

            if ((clParser.hasOption("offlineMigration"))
                    && (!mtk.schemaOnlyMode)
                    && (!safeMode)
                    && (mtk.targetDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.targetDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)) {
                System.out.println(ResourceHandler.getValue(
                        "ERR_BINARY_OFFLINE_MODE_NOT_SUPPORTED", null));
                return;
            }

            if (clParser.hasOption("targetDBType")) {
                mtk.setTargetDBType(clParser.getOption("targetDBType"));

                if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.MYSQL)
                        || (mtk.targetDBType == MTKConstants.DATABASE_TYPE.SYBASE)) {
                    Utility.getLogger().warn("");
                    Utility.getLogger().warn(
                            ResourceHandler.getValue("ERR_INVALID_TARGET_DB",
                                    null));
                    Utility.getLogger().warn(
                            ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                    return;
                }
            }
            if (clParser.hasOption("copyViaDBLinkOra"))
                if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                        && (mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)) {
                    mtk.setIsDBLinkOra(true);
                } else {
                    System.out.println(ResourceHandler.getValue(
                            "WRN_DBLINKORA_MSG", null));
                    return;
                }
            if ((clParser.hasOption("checkFunctionBodies"))
                    && ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) || (mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB))) {
                if (clParser.getOption("checkFunctionBodies").equalsIgnoreCase(
                        "false")) {
                    mtk.flagCheckFunctionBodies = false;
                }

            }

            if (clParser.hasOption("offlineMigration")) {
                mtk.setOfflineMigration(true);
            }

            if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.NPS) {
                if (!Utility.isValidExecuteable("nzload")) {
                    Utility.getLogger()
                            .warn("Netezza nzload utility not found. Make sure that nzload is in your PATH.");
                    return;
                }
                nzOptions.put("dateStyle", "YMD");
                nzOptions.put("dateDelim", "-");
                nzOptions.put("delim", "\t");
                nzOptions.put("encoding", "INTERNAL");
                if (clParser.hasOption("nzOptions")) {
                    String[] nzStr = DBUtils.split(
                            clParser.getOption("nzOptions"), ',', '\'');

                    for (int i = 0; i < nzStr.length; i++) {
                        String opt = nzStr[i];
                        String[] optVals = DBUtils.split(opt, '=', '\'');
                        if (optVals.length == 2) {
                            String val = optVals[1];
                            val = val.replace("\\t", "\t");
                            nzOptions.put(optVals[0].toLowerCase(), val);
                        } else if (optVals.length == 1) {
                            nzOptions.put(optVals[0].toLowerCase(), "");
                        } else {
                            Utility.getLogger().warn(
                                    "Invalid name value pair:" + opt);
                            return;
                        }
                    }
                    mtk.copyDelimiter = ((String) nzOptions.get("delim"))
                            .charAt(0);
                }

            }

            if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ORACLE)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.DB2)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SQLSERVER)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.MYSQL)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SYBASE)) {
                Utility.getLogger()
                        .warn("The migration to SRDB is supported only when Oracle or SRDB is the source database.");
                return;
            }

            if (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE) {
                if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) {
                    importTriggers = false;
                    importProcs = false;// false;
                    importFuncs = false;
                    importPackages = false;
                    importSynonyms = false;
                    importPublicSynonyms = false;
                    importPrivateSynonyms = false;
                    importObjectTypes = false;
                    importDBLinks = false;
                    importDefaultUser = false;
                } else if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.NPS) {
                    importIndexes = false;
                    importTriggers = false;
                    importObjectTypes = false;
                    importDBLinks = false;
                    importDefaultUser = false;
                }

            } else if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.DB2)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
                    || ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER) && ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SRDB)))) {
                importTriggers = false;
                importSequences = false;
                importProcs = false;
                importFuncs = false;
                importPackages = false;
                importSynonyms = false;
                importPublicSynonyms = false;
                importPrivateSynonyms = false;
                importObjectTypes = false;
            } else if (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SRDB) {
                if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB)
                        || (mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)) {
                    if ((!mtk.offlineMigration) && (!mtk.schemaOnlyMode)) {
                        mtk.setFastCopy(true);
                    }

                    importRules = true;
                    importDomains = true;
                }

                importProcs = false;
                importPackages = false;
                importSynonyms = false;
                importPublicSynonyms = false;
                importPrivateSynonyms = false;
                importObjectTypes = false;
                importDefaultUser = false;
            } else if (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) {
                if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) {
                    if ((!mtk.offlineMigration) && (!mtk.schemaOnlyMode)) {
                        mtk.setFastCopy(true);
                    }

                    importRules = true;
                    importDomains = true;
                    importProcs = false;
                    importPackages = false;
                    importSynonyms = false;
                    importPublicSynonyms = false;
                    importPrivateSynonyms = false;
                } else if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) {
                    if ((!mtk.offlineMigration) && (!mtk.schemaOnlyMode)) {
                        mtk.setFastCopy(true);
                    }

                    importRules = true;
                    importDomains = true;
                }

                importObjectTypes = false;
                importDefaultUser = false;
            }

            if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE)) {
                importViews = false;
            }

            if (((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL) || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE))
                    && ((clParser.hasOption("allViews")) || (clParser
                    .hasOption("views")))) {
                Utility.getLogger().warn("");
                rbParameters = new String[]{mtk.sourceDBType.getString()};
                Utility.getLogger().warn(
                        ResourceHandler.getValue("ERR_VIEWS_NOT_SUPPORTED",
                                rbParameters));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if (((clParser.hasOption("allUsers")) || (clParser
                    .hasOption("Users")))
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ORACLE)
                    && (mtk.targetDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (((mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB) && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)) || ((mtk.targetDBType != MTKConstants.DATABASE_TYPE.SRDB) && (mtk.targetDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)))) {
                rbParameters = new String[]{mtk.sourceDBType.getString()};
                System.out.println(ResourceHandler.getValue(
                        "ERR_ROLES_NOT_SUPPORTED", rbParameters));
                System.out.println(ResourceHandler.getValue("WRN_RUN_MTK_HELP",
                        null));
                return;
            }

            if ((clParser.hasOption("allTables"))
                    || (clParser.hasOption("tables"))
                    || (clParser.hasOption("constraints"))
                    || (clParser.hasOption("indexes"))
                    || (clParser.hasOption("triggers"))
                    || (clParser.hasOption("allViews"))
                    || (clParser.hasOption("views"))
                    || (clParser.hasOption("allSequences"))
                    || (clParser.hasOption("sequences"))
                    || (clParser.hasOption("allProcs"))
                    || (clParser.hasOption("procs"))
                    || (clParser.hasOption("allFuncs"))
                    || (clParser.hasOption("funcs"))
                    || (clParser.hasOption("allPackages"))
                    || (clParser.hasOption("packages"))
                    || (clParser.hasOption("synonyms"))
                    || (clParser.hasOption("allSynonyms"))
                    || (clParser.hasOption("allDBLinks"))
                    || (clParser.hasOption("objecttypes"))
                    || (clParser.hasOption("allRules"))
                    || (clParser.hasOption("rules"))
                    || (clParser.hasOption("allDomains"))
                    || (clParser.hasOption("domains"))
                    || (clParser.hasOption("allPublicSynonyms"))
                    || (clParser.hasOption("allPrivateSynonyms"))) {
                importTables = (clParser.hasOption("allTables"))
                        || (clParser.hasOption("tables"));
                importConstraints = clParser.hasOption("constraints");
                importIndexes = clParser.hasOption("indexes");
                importTriggers = clParser.hasOption("triggers");
                importViews = (clParser.hasOption("allViews"))
                        || (clParser.hasOption("views"));
                importSequences = (clParser.hasOption("allSequences"))
                        || (clParser.hasOption("sequences"));
                importProcs = (clParser.hasOption("allProcs"))
                        || (clParser.hasOption("procs"));
                importFuncs = (clParser.hasOption("allFuncs"))
                        || (clParser.hasOption("funcs"));
                importPackages = (clParser.hasOption("allPackages"))
                        || (clParser.hasOption("packages"));
                importSynonyms = (clParser.hasOption("allSynonyms"))
                        || (clParser.hasOption("synonyms"));

                if (importSynonyms) {
                    importPublicSynonyms = false;
                    importPrivateSynonyms = false;
                } else {
                    importPublicSynonyms = clParser
                            .hasOption("allPublicSynonyms");
                    importPrivateSynonyms = clParser
                            .hasOption("allPrivateSynonyms");
                }

                mtk.useOraPartitionSyntax = Boolean
                        .valueOf(
                                clParser.getOption("useOraPartitionSyntax") == null ? "true"
                                        : clParser
                                        .getOption("useOraPartitionSyntax"))
                        .booleanValue();
                importDBLinks = clParser.hasOption("allDBLinks");
                importObjectTypes = clParser.hasOption("objecttypes");
                importRules = (clParser.hasOption("allRules"))
                        || (clParser.hasOption("rules"));
                importDomains = (clParser.hasOption("allDomains"))
                        || (clParser.hasOption("domains"));

                importDefaultUser = false;
            }

            if ((clParser.hasOption("allUsers"))
                    || (clParser.hasOption("Users"))
                    || (clParser.hasOption("allGroups"))
                    || (clParser.hasOption("groups"))) {
                importGroups = (clParser.hasOption("allGroups"))
                        || (clParser.hasOption("groups"));

                importDefaultUser = false;
                mtk.setImportAllUsers((clParser.hasOption("allUsers"))
                        || (clParser.hasOption("Users")));
            }

            if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
                    || ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER) && ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SRDB)))) {
                if ((importTriggers) || (importSequences) || (importProcs)
                        || (importFuncs) || (importPackages)
                        || (importSynonyms) || (importObjectTypes)) {
                    Utility.getLogger().warn("");
                    Utility.getLogger()
                            .warn(ResourceHandler
                                    .getValue(
                                            "ERR_TRIGGER_SEQ_FUNC_SYNONYMS_NOT_SUPPORTED",
                                            null));
                    Utility.getLogger().warn(
                            ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                    return;
                }

            }

            if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB)
                    && (
//                    (importPackages) || (importProcs)
//                    ||
                    (importObjectTypes) || (importDBLinks))) {
                Utility.getLogger().warn("");
                Utility.getLogger()
                        .warn(ResourceHandler
                                .getValue(
                                        "ERR_TRIGGER_FUNC_SYN_DBLINK_NOT_SUPPORTED_IN_PG",
                                        null));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if ((mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (importRules)) {
                Utility.getLogger().warn("");
                Utility.getLogger().warn(
                        ResourceHandler.getValue("ERR_RULE_NOT_SUPPORTED",
                                new Object[]{mtk.sourceDBType}));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if ((mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (importGroups)) {
                Utility.getLogger().warn("");
                Utility.getLogger().warn(
                        ResourceHandler.getValue("ERR_GROUP_NOT_SUPPORTED",
                                new Object[]{mtk.sourceDBType}));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if ((mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (importDomains)) {
                Utility.getLogger().warn("");
                Utility.getLogger().warn(
                        ResourceHandler.getValue("ERR_DOMAINS_NOT_SUPPORTED",
                                new Object[]{mtk.sourceDBType}));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if (clParser.hasOption("edbhost")) {
                mtk.targetDBURL = clParser.getOption("edbhost");
            } else if (clParser.hasOption("targetdburl")) {
                mtk.targetDBURL = clParser.getOption("targetdburl");
            }

            if (clParser.hasOption("edbuser")) {
                mtk.targetDBUser = clParser.getOption("edbuser");
            } else if (clParser.hasOption("targetuser")) {
                mtk.targetDBUser = clParser.getOption("targetuser");
            }

            if (clParser.hasOption("edbpass")) {
                mtk.targetDBPassword = clParser.getOption("edbpass");
            } else if (clParser.hasOption("targetpass")) {
                mtk.targetDBPassword = clParser.getOption("targetpass");
            }

            if (clParser.hasOption("orahost")) {
                mtk.srcDBURL = clParser.getOption("orahost");
            } else if (clParser.hasOption("srcdburl")) {
                mtk.srcDBURL = clParser.getOption("srcdburl");
            }

            if (clParser.hasOption("orauser")) {
                mtk.srcDBUser = clParser.getOption("orauser");
            } else if (clParser.hasOption("srcuser")) {
                mtk.srcDBUser = clParser.getOption("srcuser");
            }

            if (clParser.hasOption("orapass")) {
                mtk.srcDBPassword = clParser.getOption("orapass");
            } else if (clParser.hasOption("srcpass")) {
                mtk.srcDBPassword = clParser.getOption("srcpass");
            }

            if ((clParser.hasOption("dropSchema"))
                    && (clParser.getOption("dropSchema")
                    .equalsIgnoreCase("true"))) {
                dropSchema = true;
            }

            if (mtk.dataOnlyMode) {
                copyTableDDL = false;
                importConstraints = false;
                importIndexes = false;
                importTriggers = false;
                dropSchema = false;
                importSynonyms = false;
                importPublicSynonyms = false;
                importPrivateSynonyms = false;
                importObjectTypes = false;

                importViews = false;
                importSequences = false;
                importProcs = false;
                importFuncs = false;
                importPackages = false;
                importDefaultUser = false;
            } else if (mtk.schemaOnlyMode) {
                copyTableData = false;
            }

            if (clParser.hasOption("tables")) {
                mtk.setTableNames(clParser.getOption("tables").split(","));
            }

            if (clParser.hasOption("synonyms")) {
                mtk.setSynonymNames(clParser.getOption("synonyms").split(","));
            }

            if (clParser.hasOption("views")) {
                mtk.setViewNames(clParser.getOption("views").split(","));
            }

            if (clParser.hasOption("sequences")) {
                mtk.setSequenceNames(clParser.getOption("sequences").split(","));
            }

            if (clParser.hasOption("procs")) {
                mtk.setProcNames(clParser.getOption("procs").split(","));
            }

            if (clParser.hasOption("funcs")) {
                mtk.setFuncNames(clParser.getOption("funcs").split(","));
            }

            if (clParser.hasOption("Users")) {
                mtk.setUserNames(clParser.getOption("Users").split(","));
            }

            if (clParser.hasOption("packages")) {
                mtk.setPackageNames(clParser.getOption("packages").split(","));
            }

            if (clParser.hasOption("allDBLinks")) {
                importDBLinks = true;
            }

            if (clParser.hasOption("importPartitionAsTable")) {
                importPartitionAsTable = true;
            }

            if (clParser.hasOption("rules")) {
                mtk.setRuleNames(clParser.getOption("rules").split(","));
            }

            if (clParser.hasOption("groups")) {
                mtk.setGroupNames(clParser.getOption("groups").split(","));
            }

            if (clParser.hasOption("domains")) {
                mtk.setDomainNames(clParser.getOption("domains").split(","));
            }

            if (clParser.hasOption("copyDelimiter")) {
                if (isEscapeCharacter(clParser.getOption("copyDelimiter")))
                    mtk.copyDelimiter = escapeCharacter(clParser
                            .getOption("copyDelimiter"));
                else {
                    mtk.copyDelimiter = clParser.getOption("copyDelimiter")
                            .charAt(0);
                }

            }

            if (clParser.hasOption("escapeTabDelimiter")) {
                mtk.escapeTabDelimiter = (clParser.getOption(
                        "escapeTabDelimiter").toLowerCase().equals("true"));
            }
//            System.out.println("============"+clParser.hasOption("filterProp"));
            if (clParser.hasOption("filterProp")) {
                try {
                    String filterPropFile = clParser.getOption("filterProp");
                    Properties filterProp = new Properties();
                    filterProp.load(new FileInputStream(filterPropFile));
                    mtk.setFilterProp(filterProp);
                } catch (Exception e) {
                    logMessage(ResourceHandler.getValue(
                            "ERR_PROPS_FILE_CAN_NOT_BE_LOADED", null));
                }
            }

            if (clParser.hasOption("columnsFilterProp")) {
                try {
                    String colFilterPropFile = clParser
                            .getOption("columnsFilterProp");
                    Properties colFilterProp = new Properties();
                    colFilterProp.load(new FileInputStream(colFilterPropFile));
                    mtk.setColumnFilterProp(colFilterProp);
                } catch (Exception e) {
                    logMessage(ResourceHandler.getValue(
                            "ERR_COL_FILTER_PROPS_FILE_CAN_NOT_BE_LOADED",
                            new String[]{e.getMessage()}));
                    System.exit(-1);
                }
            }

            if (clParser.hasOption("oraTxLevelSerializable")) {
                mtk.setOraTxLevelSerializable();
            }

            if (clParser.hasOption("vacuumAnalyze"))
                mtk.setVacuumAnalyze(true);
            else if (clParser.hasOption("analyze")) {
                mtk.setAnalyze(true);
            }

            if (clParser.hasOption("exitOnError")) {
                mtk.setExitOnError(true);
            }

            if (clParser.hasOption("importViewAsTable")) {
                mtk.setImportViewAsTable();
            }

            if (clParser.hasOption("skipFKConst")) {
                mtk.setSkipFKConst(true);
            }

            if (clParser.hasOption("skipCKConst")) {
                mtk.setSkipCKConst(true);
            }

            if (clParser.hasOption("enableConstBeforeDataLoad")) {
                mtk.setEnableConstBeforeDataLoad(true);
            }

            if (clParser.hasOption("ignoreCheckConstFilter"))
                setIgnoreCheckConstFilter(true);
            else {
                setIgnoreCheckConstFilter(false);
            }

            if ((clParser.hasOption("allUsers"))
                    || (clParser.hasOption("Users"))) {
                mtk.setImportAllUsers(true);
                importDefaultUser = false;
            }

            if (clParser.hasOption("skipColDefaultClause"))
                skipColDefaultClause = true;
            else {
                skipColDefaultClause = false;
            }

            if (clParser.hasOption("replaceNullChar")) {
                replaceNullChar = true;
                nullReplacementChar = clParser.getOption("replaceNullChar")
                        .charAt(0);
            } else {
                replaceNullChar = false;
            }

            if (clParser.hasOption("fastCopy")) {
                mtk.setFastCopy(true);
            }

            if (clParser.hasOption("customColTypeMapping")) {
                if (!mtk.initCustomColTypeMapping(clParser.getOption(
                        "customColTypeMapping").split(";"))) {
                    usage();
                    return;
                }
            } else if ((clParser.hasOption("customColTypeMappingFile"))
                    && (!mtk.initCustomColTypeMapping(clParser
                    .getOption("customColTypeMappingFile")))) {
                usage();
                return;
            }
            mtk.initToolkit(propFile);

            if (clParser.hasOption("allSchemas")) {
                MTKMetaData md = mtk.mtkFactory.createMTKMetaData(
                        mtk.sourceDBType, mtk.srcConn);
                schemaList = md.getSchemas();
                try {
                    md.closeScriptWriters();
                    md = null;
                } catch (Exception e) {
                }
            }

            sourceToTargetMappings = new Hashtable();
            if (schemaList != null) {
                for (int i = 0; i < schemaList.length; i++) {
                    String schm = schemaList[i];
                    String targetSchemaName = null;
                    if ((targetSchemaList != null)
                            && (targetSchemaList.length > i)) {
                        targetSchemaName = targetSchemaList[i];
                        if (((mtk.getTargetDBType() == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk
                                .getTargetDBType() == MTKConstants.DATABASE_TYPE.SRDB))
                                && (targetSchemaName.equals(targetSchemaName
                                .toUpperCase()))) {
                            targetSchemaName = targetSchemaName.toLowerCase();
                        }
                    } else {
                        targetSchemaName = schm;
                        if (!Utility.isCaseSensitive(targetSchemaName,
                                mtk.sourceDBType)) {
                            targetSchemaName = Utility.convertToDefaultCase(
                                    targetSchemaName, mtk.targetDBType);
                        }
                    }
                    sourceToTargetMappings.put(schm, targetSchemaName);
                }
            }

            if (schemaList != null) {
                for (int i = 0; i < schemaList.length; i++) {
                    sourceSchema = schemaList[i];

                    if ((targetSchemaList != null)
                            && (targetSchemaList.length > i)) {
                        String targetSchemaName = targetSchemaList[i];

                        if (((mtk.getTargetDBType() == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk
                                .getTargetDBType() == MTKConstants.DATABASE_TYPE.SRDB))
                                && (targetSchemaName.equals(targetSchemaName
                                .toUpperCase()))) {
                            targetSchemaName = targetSchemaName.toLowerCase();
                        }

                        mtk.setTargetSchema(targetSchemaName);
                        mtk.setFlagUserSpecifiedTargetSchemaName(true);
                    } else {
                        String targetSchemaName = sourceSchema;
                        if (!Utility.isCaseSensitive(sourceSchema,
                                mtk.sourceDBType)) {
                            targetSchemaName = Utility.convertToDefaultCase(
                                    targetSchemaName, mtk.targetDBType);
                        }

                        mtk.setTargetSchema(targetSchemaName);
                    }

                    if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                            || (mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB)) {
                        if ((mtk.targetSchema.equals("information_schema"))
                                || (mtk.targetSchema.equals("dbo"))
                                || (mtk.targetSchema.equals("sys"))
                                || (mtk.targetSchema.equals("sr_catalog"))) {
                            if (mtk.getGenStats()) {
                                throw new MTKException(
                                        ResourceHandler.getValue(
                                                "ERR_SYSTEM_SCHEMA",
                                                new String[]{mtk.targetDBType
                                                        .getString()}));
                            }
                            failureCount += 1;
                            logMessage(
                                    ResourceHandler.getValue(
                                            "ERR_SYSTEM_SCHEMA",
                                            new String[]{mtk.targetDBType
                                                    .getString()}),
                                    Level.ERROR);

                            continue;
                        }
                    } else if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
                            && (mtk.targetSchema.equals("public"))) {
                        if (mtk.getGenStats()) {
                            throw new MTKException(ResourceHandler.getValue(
                                    "ERR_INVALID_SCHEMA_NAME",
                                    new String[]{mtk.targetSchema,
                                            mtk.targetDBType.getString()}));
                        }
                        failureCount += 1;
                        logMessage(ResourceHandler.getValue(
                                        "ERR_INVALID_SCHEMA_NAME",
                                        new String[]{mtk.targetSchema,
                                                mtk.targetDBType.getString()}),
                                Level.ERROR);

                        continue;
                    }

                    if (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE
                            || mtk.sourceDBType == MTKConstants.DATABASE_TYPE.DB2) {
                        // oracle的schema大写
                        // db2的schema大写
                        mtk.setSourceSchema(sourceSchema.toUpperCase());
                    } else
                        mtk.setSourceSchema(sourceSchema);

                    mtk.initMetaData();
                    // 对目标数据库进行表解析包括表名、每个表的条数等
                    if (mtk.parseOnlyMode) {
                        if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)) {
                            logMessage(ResourceHandler.getValue(
                                    "INFO_PARSE_DB", new String[]{
                                            mtk.sourceDBType.toString(),
                                            mtk.srcDBUser}));
                            // TODO
                            // 扫描并把表名和对应的行数记录到文件 info_tables.txt
                            mtk.sourceMD.parseTables();
                            // 调用专门的解析处理类，将info_tables.txt文件分析。
                            TableParser.parseOra(mtk.sourceMD);
                        }
                        return;

                    }
                    mtk.importSchema(sourceSchema, copyTableDDL, copyTableData,
                            dropSchema, importTables, importConstraints,
                            importIndexes, importSynonyms, importTriggers,
                            importViews, importSequences, importProcs,
                            importFuncs, importPackages, importDBLinks,
                            importObjectTypes, importRules, truncBeforeLoad,
                            safeMode, importDomains, importPublicSynonyms,
                            importPrivateSynonyms);

                    if (i == 0) {
                        mtk.isfirstSchemaMigrated = true;
                    }

                }

            }

            if ((schemaList != null)
                    && ((schemaList.length > 1) || (mtk.flagGenStats))) {
                for (int retryIndex = 1; retryIndex <= retryCount; retryIndex++) {
                    for (int i = 0; i < schemaList.length; i++) {
                        if (mtk.summary.getFailedCount(schemaList[i]) <= 0)
                            continue;
                        Utility.getLogger().info("");
                        Utility.getLogger().info(
                                ResourceHandler.getValue(
                                        "INFO_FAILED_OBJECTS_CREATION",
                                        new String[]{
                                                String.valueOf(retryIndex),
                                                schemaList[i]}));

                        String targetSchemaName = schemaList[i];

                        if ((targetSchemaList != null)
                                && (targetSchemaList.length > i)) {
                            targetSchemaName = targetSchemaList[i];

                            if ((mtk.getTargetDBType() == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                                    && (targetSchemaName
                                    .equals(targetSchemaName
                                            .toUpperCase()))) {
                                targetSchemaName = targetSchemaName
                                        .toLowerCase();
                            }

                            mtk.setTargetSchema(targetSchemaName);
                            mtk.setFlagUserSpecifiedTargetSchemaName(true);
                        } else {
                            if (!Utility.isCaseSensitive(sourceSchema,
                                    mtk.sourceDBType)) {
                                targetSchemaName = Utility
                                        .convertToDefaultCase(targetSchemaName,
                                                mtk.targetDBType);
                            }

                            mtk.setTargetSchema(targetSchemaName);
                        }

                        if ((!mtk.offlineMigration)
                                && ((mtk.getTargetDBType() == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk
                                .getTargetDBType() == MTKConstants.DATABASE_TYPE.SRDB))) {
                            mtk.configPGGUCs(targetSchemaName,
                                    mtk.getTargetDBType(), mtk.targetMD);

                            mtk.targetConn.commit();
                        }

                        mtk.copySequences(mtk.summary
                                .getFailedSequences(schemaList[i]));

                        mtk.copyDomains(mtk.summary
                                .getFailedDomains(schemaList[i]));

                        mtk.copyTables(
                                mtk.summary.getFailedTables(schemaList[i]),
                                copyTableDDL, copyTableData, truncBeforeLoad,
                                safeMode, mtk.copyDelimiter);

                        mtk.copyConstraints(mtk.summary
                                .getFailedConstraints(schemaList[i]));

                        mtk.copyIndexes(mtk.summary
                                .getFailedIndexes(schemaList[i]));

                        mtk.copyTriggers(mtk.summary
                                .getFailedTriggers(schemaList[i]));

                        mtk.copyProcedures(mtk.summary
                                .getFailedProcedures(schemaList[i]));

                        mtk.copyFunctions(mtk.summary
                                .getFailedFunctions(schemaList[i]));

                        mtk.copyPackages(mtk.summary
                                .getFailedPackages(schemaList[i]));

                        mtk.copyViews(mtk.summary.getFailedViews(schemaList[i]));
                    }

                    boolean failedObjectFlag = false;
                    for (int i = 0; i < schemaList.length; i++) {
                        if (mtk.summary.getFailedCount(schemaList[i]) > 0) {
                            failedObjectFlag = true;
                            break;
                        }

                    }

                    if (!failedObjectFlag) {
                        failureCount = 0;
                        break;
                    }

                }

            }

            if (schemaList == null)
                mtk.initMetaData();
            if (mtk.isImportAllUsers()) {
                mtk.migrateUsers();
            } else if ((importDefaultUser)
                    && (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)) {
                mtk.setUserNames(new String[]{sourceSchema});
                mtk.migrateUsers();
            }

            if (importGroups) {
                mtk.copyGroups(mtk.groupNames);
            }

            if ((mtk.isImportAllUsers())
                    || ((importDefaultUser) && (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE))) {
                mtk.migrateGrants();
            }
        } catch (Exception e) {
            failureCount += 1;

            rbParameters = new String[]{e.getMessage()};
            Utility.getLogger().warn(
                    ResourceHandler.getValue("ERR_ERROR_WITH_MESSAGE",
                            rbParameters));
            Utility.getLogger().error("Stack Trace:", e);

            if (mtk.getGenStats()) {
                mtk.setRepStatsProperty("STATUS", "F");
                mtk.setRepStatsProperty("ERROR_MESSAGE", e.getMessage());
            }
        } finally {
            if (mtk.getGenStats()) {
                mtk.saveRepStats();
            }
            mtk.closeConnections();
        }

        Utility.getLogger().info("");

        if ((mtk.summary.getFailedCount() == 0) && (failureCount == 0)
                && (fatalErrorCount == 0))
            logMessage(ResourceHandler.getValue(
                    "INFO_MIGRATION_PROCESS_COMPLETED_SUCC", null));
        else {
            logMessage(ResourceHandler.getValue(
                    "INFO_MIGRATION_PROCESS_COMPLETED_FAIL", null));
        }

        if (logFile != null) {
            Utility.getLogger().info(
                    "\n"
                            + ResourceHandler.getValue(
                            "INFO_MIGRATION_LOG_LOC",
                            new String[]{logFile}));
        }

        if (!mtk.offlineMigration) {
            String summaryText = mtk.summary.getSummary();

            if ((summaryText != null) && (summaryText.length() > 0))
                Utility.getLogger()
                        .info("\n******************** "
                                + ResourceHandler.getValue(
                                "INFO_MIGRATION_SUMMARY_LABEL", null)
                                + " ********************\n"
                                + summaryText
                                + "\n*************************************************************");
        }
    }

    /**
     *
     */
    public static void executeMigration(String[] args, DBInfo srcDb, DBInfo targetDb, IUIOperation uiOperation) {
        /**
         * 初始化统计数据
         */
        tableNum = 0;
        migratedTables = 0;
        indexNum = 0;
        migratedIndexes = 0;
        constraintsNum = 0; //源数据库约束数目
        migratedConstraints = 0; //已迁移约束数目
        viewNum = 0; //源数据库视图数目
        migratedViews = 0; //已迁移视图数目
        migrateTableFlag = false;
        migrateIndexFlag = false;
        migrateConstraintsFlag = false;
        migrateViewFlag = false;
        migrateFlag = false;
        iuiOperation = uiOperation;

        if ((args == null) || (args.length == 0)) {
            configureLogging(null);
            usage();
            return;
        }

        String sourceSchema = null;
        String propFile = null;

        boolean copyTableData = true;
        boolean copyTableDDL = true;
        boolean importTables = true;
        boolean importConstraints = true;
        boolean importIndexes = true;
        boolean importTriggers = true;
        boolean importViews = true;
        boolean importSequences = true;
        boolean importProcs = true;
        boolean importFuncs = true;
        boolean importSynonyms = true;
        boolean importPublicSynonyms = false;
        boolean importPrivateSynonyms = false;
        boolean importPackages = true;
        boolean importObjectTypes = true;
        boolean importRules = false;
        boolean importGroups = false;
        boolean importDomains = false;

        boolean importDefaultUser = true;
        boolean dropSchema = false;
        boolean truncBeforeLoad = false;
        boolean safeMode = false;
        boolean importDBLinks = false;
        failureCount = 0;
        fatalErrorCount = 0;
        lastErrorMessage = null;
        propFile = System.getProperty("prop");

        mtkInstance = null;
        MigrationToolkit mtk = getInstance();
        nzOptions.clear();
        mtk.resetSummary();
        try {
            CLParser clParser = new CLParser();

            if (!clParser.parseArgs(args)) {
                System.out.println("");
                System.out.println(ResourceHandler.getValue(
                        "WRN_INVALID_COMMAND_LINE_ARG", null));
                return;
            }

//            System.out.println("***********clparser:" + clParser);

            String srcSchema = "";
            boolean hasUser = false;
            boolean multipleSchemas = false;

            if (!clParser.hasOption("allSchemas")) {
                if (args.length >= 2) {
                    String secondLastOption = args[(args.length - 2)];
                    if (secondLastOption.equalsIgnoreCase("-Users")) {
                        hasUser = true;
                    } else if ((isKeyValueOption(secondLastOption.substring(1,
                            secondLastOption.length())))
                            && (!secondLastOption
                            .equalsIgnoreCase("-allDBLinks"))
                            && (!secondLastOption
                            .equalsIgnoreCase("-importPartitionAsTable"))
                            && (!secondLastOption
                            .equalsIgnoreCase("-offlineMigration"))) {
                        System.out.println(ResourceHandler.getValue(
                                "WRN_INVALID_COMMAND_LINE_ARG", null));
                        return;
                    }

                }

                if (!hasUser) {
                    srcSchema = args[(args.length - 1)];
                }

            } else {
                if (!args[(args.length - 1)].equalsIgnoreCase("-allSchemas")) {
                    logMessageToSystemOut(ResourceHandler.getValue(
                            "ERR_ALL_SCHEMA_LAST", null));
                    return;
                }
                multipleSchemas = true;
            }

            String[] schemaList = null;
            if ((!clParser.hasOption("allSchemas"))
                    && (!srcSchema.startsWith("-")) && (!srcSchema.equals(""))) {
                schemaList = DBUtils.split(srcSchema, ',', '"');
                multipleSchemas = schemaList.length > 1;
            }

            String[] targetSchemaList = null;
            if (clParser.hasOption("targetSchema")) {
                String targetSchema = clParser.getOption("targetSchema");

                targetSchemaList = DBUtils.split(targetSchema, ',', '"');
            }

            if (!validateOptions(clParser, multipleSchemas)) {
                return;
            }
            if (clParser.hasOption("logDir"))
                configureLogging(clParser.getOption("logDir"));
            else {
                configureLogging(null);
            }
            if ((clParser.hasOption("verbose"))
                    && (clParser.getOption("verbose").equalsIgnoreCase("off"))) {
                VERBOSE = false;
            }

            if (clParser.hasOption("help")) {
                usage();
                return;
            }
            if (clParser.hasOption("version")) {
                Utility.getLogger().info("SRDB Migration Toolkit (Build 46)");
                return;
            }
            if (clParser.hasOption("genStats")) {
                mtk.setGenStats(true);
                mtk.initRepStats();
            }

            if (clParser.hasOption("statsFile")) {
                mtk.setStatsFileName(clParser.getOption("statsFile"));
            }

            if ((!clParser.hasOption("allUsers"))
                    && ((srcSchema.startsWith("--")) || (srcSchema
                    .startsWith("-")))) {
                System.out.println("");
                System.out.println(ResourceHandler.getValue(
                        "WRN_INVALID_COMMAND_LINE_ARG", null));
                return;
            }
            mtk.schemaOnlyMode = clParser.hasOption("schemaOnly");
            mtk.dataOnlyMode = clParser.hasOption("dataOnly");
            mtk.parseOnlyMode = clParser.hasOption("parseOnly");

            truncBeforeLoad = clParser.hasOption("truncLoad");
            safeMode = clParser.hasOption("safeMode");
            mtk.useSingleDataFile = clParser.hasOption("singleDataFile");

            if (clParser.hasOption("sourceDBType")) {
                mtk.setSourceDBType(clParser.getOption("sourceDBType"));
            }

            if (clParser.hasOption("replicationMode")) {
                mtk.setReplicationMode(clParser.getOption("replicationMode"));
            }

            if ((clParser.hasOption("offlineMigration"))
                    && (!mtk.schemaOnlyMode)
                    && (!safeMode)
                    && (mtk.targetDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.targetDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)) {
                System.out.println(ResourceHandler.getValue(
                        "ERR_BINARY_OFFLINE_MODE_NOT_SUPPORTED", null));
                return;
            }

            if (clParser.hasOption("targetDBType")) {
                mtk.setTargetDBType(clParser.getOption("targetDBType"));

                if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.MYSQL)
                        || (mtk.targetDBType == MTKConstants.DATABASE_TYPE.SYBASE)) {
                    Utility.getLogger().warn("");
                    Utility.getLogger().warn(
                            ResourceHandler.getValue("ERR_INVALID_TARGET_DB",
                                    null));
                    Utility.getLogger().warn(
                            ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                    return;
                }
            }
            if (clParser.hasOption("copyViaDBLinkOra"))
                if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                        && (mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)) {
                    mtk.setIsDBLinkOra(true);
                } else {
                    System.out.println(ResourceHandler.getValue(
                            "WRN_DBLINKORA_MSG", null));
                    return;
                }
            if ((clParser.hasOption("checkFunctionBodies"))
                    && ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) || (mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB))) {
                if (clParser.getOption("checkFunctionBodies").equalsIgnoreCase(
                        "false")) {
                    mtk.flagCheckFunctionBodies = false;
                }

            }

            if (clParser.hasOption("offlineMigration")) {
                mtk.setOfflineMigration(true);
            }

            if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.NPS) {
                if (!Utility.isValidExecuteable("nzload")) {
                    Utility.getLogger()
                            .warn("Netezza nzload utility not found. Make sure that nzload is in your PATH.");
                    return;
                }
                nzOptions.put("dateStyle", "YMD");
                nzOptions.put("dateDelim", "-");
                nzOptions.put("delim", "\t");
                nzOptions.put("encoding", "INTERNAL");
                if (clParser.hasOption("nzOptions")) {
                    String[] nzStr = DBUtils.split(
                            clParser.getOption("nzOptions"), ',', '\'');

                    for (int i = 0; i < nzStr.length; i++) {
                        String opt = nzStr[i];
                        String[] optVals = DBUtils.split(opt, '=', '\'');
                        if (optVals.length == 2) {
                            String val = optVals[1];
                            val = val.replace("\\t", "\t");
                            nzOptions.put(optVals[0].toLowerCase(), val);
                        } else if (optVals.length == 1) {
                            nzOptions.put(optVals[0].toLowerCase(), "");
                        } else {
                            Utility.getLogger().warn(
                                    "Invalid name value pair:" + opt);
                            return;
                        }
                    }
                    mtk.copyDelimiter = ((String) nzOptions.get("delim"))
                            .charAt(0);
                }

            }

            if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ORACLE)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.DB2)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SQLSERVER)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.MYSQL)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SYBASE)) {
                Utility.getLogger()
                        .warn("The migration to SRDB is supported only when Oracle or SRDB is the source database.");
                return;
            }

            if (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE) {
                if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) {
                    importTriggers = false;
                    importProcs = false;// false;
                    importFuncs = false;
                    importPackages = false;
                    importSynonyms = false;
                    importPublicSynonyms = false;
                    importPrivateSynonyms = false;
                    importObjectTypes = false;
                    importDBLinks = false;
                    importDefaultUser = false;
                } else if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.NPS) {
                    importIndexes = false;
                    importTriggers = false;
                    importObjectTypes = false;
                    importDBLinks = false;
                    importDefaultUser = false;
                }

            } else if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.DB2)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
                    || ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER) && ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SRDB)))) {
                importTriggers = false;
                importSequences = false;
                importProcs = false;
                importFuncs = false;
                importPackages = false;
                importSynonyms = false;
                importPublicSynonyms = false;
                importPrivateSynonyms = false;
                importObjectTypes = false;
            } else if (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SRDB) {
                if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB)
                        || (mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)) {
                    if ((!mtk.offlineMigration) && (!mtk.schemaOnlyMode)) {
                        mtk.setFastCopy(true);
                    }

                    importRules = true;
                    importDomains = true;
                }

                importProcs = false;
                importPackages = false;
                importSynonyms = false;
                importPublicSynonyms = false;
                importPrivateSynonyms = false;
                importObjectTypes = false;
                importDefaultUser = false;
            } else if (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) {
                if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) {
                    if ((!mtk.offlineMigration) && (!mtk.schemaOnlyMode)) {
                        mtk.setFastCopy(true);
                    }

                    importRules = true;
                    importDomains = true;
                    importProcs = false;
                    importPackages = false;
                    importSynonyms = false;
                    importPublicSynonyms = false;
                    importPrivateSynonyms = false;
                } else if (mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) {
                    if ((!mtk.offlineMigration) && (!mtk.schemaOnlyMode)) {
                        mtk.setFastCopy(true);
                    }

                    importRules = true;
                    importDomains = true;
                }

                importObjectTypes = false;
                importDefaultUser = false;
            }

            if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE)) {
                importViews = false;
            }

            if (((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL) || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE))
                    && ((clParser.hasOption("allViews")) || (clParser
                    .hasOption("views")))) {
                Utility.getLogger().warn("");
                rbParameters = new String[]{mtk.sourceDBType.getString()};
                Utility.getLogger().warn(
                        ResourceHandler.getValue("ERR_VIEWS_NOT_SUPPORTED",
                                rbParameters));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if (((clParser.hasOption("allUsers")) || (clParser
                    .hasOption("Users")))
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ORACLE)
                    && (mtk.targetDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (((mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB) && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)) || ((mtk.targetDBType != MTKConstants.DATABASE_TYPE.SRDB) && (mtk.targetDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)))) {
                rbParameters = new String[]{mtk.sourceDBType.getString()};
                System.out.println(ResourceHandler.getValue(
                        "ERR_ROLES_NOT_SUPPORTED", rbParameters));
                System.out.println(ResourceHandler.getValue("WRN_RUN_MTK_HELP",
                        null));
                return;
            }

            if ((clParser.hasOption("allTables"))
                    || (clParser.hasOption("tables"))
                    || (clParser.hasOption("constraints"))
                    || (clParser.hasOption("indexes"))
                    || (clParser.hasOption("triggers"))
                    || (clParser.hasOption("allViews"))
                    || (clParser.hasOption("views"))
                    || (clParser.hasOption("allSequences"))
                    || (clParser.hasOption("sequences"))
                    || (clParser.hasOption("allProcs"))
                    || (clParser.hasOption("procs"))
                    || (clParser.hasOption("allFuncs"))
                    || (clParser.hasOption("funcs"))
                    || (clParser.hasOption("allPackages"))
                    || (clParser.hasOption("packages"))
                    || (clParser.hasOption("synonyms"))
                    || (clParser.hasOption("allSynonyms"))
                    || (clParser.hasOption("allDBLinks"))
                    || (clParser.hasOption("objecttypes"))
                    || (clParser.hasOption("allRules"))
                    || (clParser.hasOption("rules"))
                    || (clParser.hasOption("allDomains"))
                    || (clParser.hasOption("domains"))
                    || (clParser.hasOption("allPublicSynonyms"))
                    || (clParser.hasOption("allPrivateSynonyms"))) {
                importTables = (clParser.hasOption("allTables"))
                        || (clParser.hasOption("tables"));
                importConstraints = clParser.hasOption("constraints");
                importIndexes = clParser.hasOption("indexes");
                importTriggers = clParser.hasOption("triggers");
                importViews = (clParser.hasOption("allViews"))
                        || (clParser.hasOption("views"));
                importSequences = (clParser.hasOption("allSequences"))
                        || (clParser.hasOption("sequences"));
                importProcs = (clParser.hasOption("allProcs"))
                        || (clParser.hasOption("procs"));
                importFuncs = (clParser.hasOption("allFuncs"))
                        || (clParser.hasOption("funcs"));
                importPackages = (clParser.hasOption("allPackages"))
                        || (clParser.hasOption("packages"));
                importSynonyms = (clParser.hasOption("allSynonyms"))
                        || (clParser.hasOption("synonyms"));

                if (importSynonyms) {
                    importPublicSynonyms = false;
                    importPrivateSynonyms = false;
                } else {
                    importPublicSynonyms = clParser
                            .hasOption("allPublicSynonyms");
                    importPrivateSynonyms = clParser
                            .hasOption("allPrivateSynonyms");
                }

                mtk.useOraPartitionSyntax = Boolean
                        .valueOf(
                                clParser.getOption("useOraPartitionSyntax") == null ? "true"
                                        : clParser
                                        .getOption("useOraPartitionSyntax"))
                        .booleanValue();
                importDBLinks = clParser.hasOption("allDBLinks");
                importObjectTypes = clParser.hasOption("objecttypes");
                importRules = (clParser.hasOption("allRules"))
                        || (clParser.hasOption("rules"));
                importDomains = (clParser.hasOption("allDomains"))
                        || (clParser.hasOption("domains"));

                importDefaultUser = false;
            }

            if ((clParser.hasOption("allUsers"))
                    || (clParser.hasOption("Users"))
                    || (clParser.hasOption("allGroups"))
                    || (clParser.hasOption("groups"))) {
                importGroups = (clParser.hasOption("allGroups"))
                        || (clParser.hasOption("groups"));

                importDefaultUser = false;
                mtk.setImportAllUsers((clParser.hasOption("allUsers"))
                        || (clParser.hasOption("Users")));
            }

            if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE)
                    || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
                    || ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER) && ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.SRDB)))) {
                if ((importTriggers) || (importSequences) || (importProcs)
                        || (importFuncs) || (importPackages)
                        || (importSynonyms) || (importObjectTypes)) {
                    Utility.getLogger().warn("");
                    Utility.getLogger()
                            .warn(ResourceHandler
                                    .getValue(
                                            "ERR_TRIGGER_SEQ_FUNC_SYNONYMS_NOT_SUPPORTED",
                                            null));
                    Utility.getLogger().warn(
                            ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                    return;
                }

            }

            if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB)
                    && (
//                    (importPackages) || (importProcs)
//                    ||
                    (importObjectTypes) || (importDBLinks))) {
                Utility.getLogger().warn("");
                Utility.getLogger()
                        .warn(ResourceHandler
                                .getValue(
                                        "ERR_TRIGGER_FUNC_SYN_DBLINK_NOT_SUPPORTED_IN_PG",
                                        null));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if ((mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (importRules)) {
                Utility.getLogger().warn("");
                Utility.getLogger().warn(
                        ResourceHandler.getValue("ERR_RULE_NOT_SUPPORTED",
                                new Object[]{mtk.sourceDBType}));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if ((mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (importGroups)) {
                Utility.getLogger().warn("");
                Utility.getLogger().warn(
                        ResourceHandler.getValue("ERR_GROUP_NOT_SUPPORTED",
                                new Object[]{mtk.sourceDBType}));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if ((mtk.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)
                    && (mtk.sourceDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    && (importDomains)) {
                Utility.getLogger().warn("");
                Utility.getLogger().warn(
                        ResourceHandler.getValue("ERR_DOMAINS_NOT_SUPPORTED",
                                new Object[]{mtk.sourceDBType}));
                Utility.getLogger().warn(
                        ResourceHandler.getValue("WRN_RUN_MTK_HELP", null));
                return;
            }
            if (clParser.hasOption("edbhost")) {
                mtk.targetDBURL = clParser.getOption("edbhost");
            } else if (clParser.hasOption("targetdburl")) {
                mtk.targetDBURL = clParser.getOption("targetdburl");
            }

            if (clParser.hasOption("edbuser")) {
                mtk.targetDBUser = clParser.getOption("edbuser");
            } else if (clParser.hasOption("targetuser")) {
                mtk.targetDBUser = clParser.getOption("targetuser");
            }

            if (clParser.hasOption("edbpass")) {
                mtk.targetDBPassword = clParser.getOption("edbpass");
            } else if (clParser.hasOption("targetpass")) {
                mtk.targetDBPassword = clParser.getOption("targetpass");
            }

            if (clParser.hasOption("orahost")) {
                mtk.srcDBURL = clParser.getOption("orahost");
            } else if (clParser.hasOption("srcdburl")) {
                mtk.srcDBURL = clParser.getOption("srcdburl");
            }

            if (clParser.hasOption("orauser")) {
                mtk.srcDBUser = clParser.getOption("orauser");
            } else if (clParser.hasOption("srcuser")) {
                mtk.srcDBUser = clParser.getOption("srcuser");
            }

            if (clParser.hasOption("orapass")) {
                mtk.srcDBPassword = clParser.getOption("orapass");
            } else if (clParser.hasOption("srcpass")) {
                mtk.srcDBPassword = clParser.getOption("srcpass");
            }

            if ((clParser.hasOption("dropSchema"))
                    && (clParser.getOption("dropSchema")
                    .equalsIgnoreCase("true"))) {
                dropSchema = true;
            }

            if (mtk.dataOnlyMode) {
                copyTableDDL = false;
                importConstraints = false;
                importIndexes = false;
                importTriggers = false;
                dropSchema = false;
                importSynonyms = false;
                importPublicSynonyms = false;
                importPrivateSynonyms = false;
                importObjectTypes = false;

                importViews = false;
                importSequences = false;
                importProcs = false;
                importFuncs = false;
                importPackages = false;
                importDefaultUser = false;
            } else if (mtk.schemaOnlyMode) {
                copyTableData = false;
            }

            if (clParser.hasOption("tables")) {
                mtk.setTableNames(clParser.getOption("tables").split(","));
            }

            if (clParser.hasOption("synonyms")) {
                mtk.setSynonymNames(clParser.getOption("synonyms").split(","));
            }

            if (clParser.hasOption("views")) {
                mtk.setViewNames(clParser.getOption("views").split(","));
            }

            if (clParser.hasOption("sequences")) {
                mtk.setSequenceNames(clParser.getOption("sequences").split(","));
            }

            if (clParser.hasOption("procs")) {
                mtk.setProcNames(clParser.getOption("procs").split(","));
            }

            if (clParser.hasOption("funcs")) {
                mtk.setFuncNames(clParser.getOption("funcs").split(","));
            }

            if (clParser.hasOption("Users")) {
                mtk.setUserNames(clParser.getOption("Users").split(","));
            }

            if (clParser.hasOption("packages")) {
                mtk.setPackageNames(clParser.getOption("packages").split(","));
            }

            if (clParser.hasOption("allDBLinks")) {
                importDBLinks = true;
            }

            if (clParser.hasOption("importPartitionAsTable")) {
                importPartitionAsTable = true;
            }

            if (clParser.hasOption("rules")) {
                mtk.setRuleNames(clParser.getOption("rules").split(","));
            }

            if (clParser.hasOption("groups")) {
                mtk.setGroupNames(clParser.getOption("groups").split(","));
            }

            if (clParser.hasOption("domains")) {
                mtk.setDomainNames(clParser.getOption("domains").split(","));
            }

            if (clParser.hasOption("copyDelimiter")) {
                if (isEscapeCharacter(clParser.getOption("copyDelimiter")))
                    mtk.copyDelimiter = escapeCharacter(clParser
                            .getOption("copyDelimiter"));
                else {
                    mtk.copyDelimiter = clParser.getOption("copyDelimiter")
                            .charAt(0);
                }

            }

            if (clParser.hasOption("escapeTabDelimiter")) {
                mtk.escapeTabDelimiter = (clParser.getOption(
                        "escapeTabDelimiter").toLowerCase().equals("true"));
            }
//            System.out.println("============"+clParser.hasOption("filterProp"));
            if (clParser.hasOption("filterProp")) {
                try {
                    String filterPropFile = clParser.getOption("filterProp");
                    Properties filterProp = new Properties();
                    filterProp.load(new FileInputStream(filterPropFile));
                    mtk.setFilterProp(filterProp);
                } catch (Exception e) {
                    logMessage(ResourceHandler.getValue(
                            "ERR_PROPS_FILE_CAN_NOT_BE_LOADED", null));
                }
            }

            if (clParser.hasOption("columnsFilterProp")) {
                try {
                    String colFilterPropFile = clParser
                            .getOption("columnsFilterProp");
                    Properties colFilterProp = new Properties();
                    colFilterProp.load(new FileInputStream(colFilterPropFile));
                    mtk.setColumnFilterProp(colFilterProp);
                } catch (Exception e) {
                    logMessage(ResourceHandler.getValue(
                            "ERR_COL_FILTER_PROPS_FILE_CAN_NOT_BE_LOADED",
                            new String[]{e.getMessage()}));
                    System.exit(-1);
                }
            }

            if (clParser.hasOption("oraTxLevelSerializable")) {
                mtk.setOraTxLevelSerializable();
            }

            if (clParser.hasOption("vacuumAnalyze"))
                mtk.setVacuumAnalyze(true);
            else if (clParser.hasOption("analyze")) {
                mtk.setAnalyze(true);
            }

            if (clParser.hasOption("exitOnError")) {
                mtk.setExitOnError(true);
            }

            if (clParser.hasOption("importViewAsTable")) {
                mtk.setImportViewAsTable();
            }

            if (clParser.hasOption("skipFKConst")) {
                mtk.setSkipFKConst(true);
            }

            if (clParser.hasOption("skipCKConst")) {
                mtk.setSkipCKConst(true);
            }

            if (clParser.hasOption("enableConstBeforeDataLoad")) {
                mtk.setEnableConstBeforeDataLoad(true);
            }

            if (clParser.hasOption("ignoreCheckConstFilter"))
                setIgnoreCheckConstFilter(true);
            else {
                setIgnoreCheckConstFilter(false);
            }

            if ((clParser.hasOption("allUsers"))
                    || (clParser.hasOption("Users"))) {
                mtk.setImportAllUsers(true);
                importDefaultUser = false;
            }

            if (clParser.hasOption("skipColDefaultClause"))
                skipColDefaultClause = true;
            else {
                skipColDefaultClause = false;
            }

            if (clParser.hasOption("replaceNullChar")) {
                replaceNullChar = true;
                nullReplacementChar = clParser.getOption("replaceNullChar")
                        .charAt(0);
            } else {
                replaceNullChar = false;
            }

            if (clParser.hasOption("fastCopy")) {
                mtk.setFastCopy(true);
            }

            if (clParser.hasOption("customColTypeMapping")) {
                if (!mtk.initCustomColTypeMapping(clParser.getOption(
                        "customColTypeMapping").split(";"))) {
                    usage();
                    return;
                }
            } else if ((clParser.hasOption("customColTypeMappingFile"))
                    && (!mtk.initCustomColTypeMapping(clParser
                    .getOption("customColTypeMappingFile")))) {
                usage();
                return;
            }

            mtk.srcDBURL = Util.getConnectionURL(srcDb);
            mtk.srcDBUser = srcDb.getUserName();
            mtk.srcDBPassword = srcDb.getPassword();
            mtk.targetDBURL = Util.getConnectionURL(targetDb);
            mtk.targetDBUser = targetDb.getUserName();
            mtk.targetDBPassword = targetDb.getPassword();
            mtk.initToolkitWithoutPropFile();

            if (clParser.hasOption("allSchemas")) {
                MTKMetaData md = mtk.mtkFactory.createMTKMetaData(
                        mtk.sourceDBType, mtk.srcConn);
                schemaList = md.getSchemas();
                try {
                    md.closeScriptWriters();
                    md = null;
                } catch (Exception e) {
                }
            }

            sourceToTargetMappings = new Hashtable();
            if (schemaList != null) {
                for (int i = 0; i < schemaList.length; i++) {
                    String schm = schemaList[i];
                    String targetSchemaName = null;
                    if ((targetSchemaList != null)
                            && (targetSchemaList.length > i)) {
                        targetSchemaName = targetSchemaList[i];
                        if (((mtk.getTargetDBType() == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk
                                .getTargetDBType() == MTKConstants.DATABASE_TYPE.SRDB))
                                && (targetSchemaName.equals(targetSchemaName
                                .toUpperCase()))) {
                            targetSchemaName = targetSchemaName.toLowerCase();
                        }
                    } else {
                        targetSchemaName = schm;
                        if (!Utility.isCaseSensitive(targetSchemaName,
                                mtk.sourceDBType)) {
                            targetSchemaName = Utility.convertToDefaultCase(
                                    targetSchemaName, mtk.targetDBType);
                        }
                    }
                    sourceToTargetMappings.put(schm, targetSchemaName);
                }
            }

            /****
             *
             *
             *
             *
             *
             *
             *
             *
             *
             *
             */
            if (schemaList != null) {
                for (int i = 0; i < schemaList.length; i++) {
                    sourceSchema = schemaList[i];

                    if ((targetSchemaList != null)
                            && (targetSchemaList.length > i)) {
                        String targetSchemaName = targetSchemaList[i];

                        if (((mtk.getTargetDBType() == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk
                                .getTargetDBType() == MTKConstants.DATABASE_TYPE.SRDB))
                                && (targetSchemaName.equals(targetSchemaName
                                .toUpperCase()))) {
                            targetSchemaName = targetSchemaName.toLowerCase();
                        }

                        mtk.setTargetSchema(targetSchemaName);
                        mtk.setFlagUserSpecifiedTargetSchemaName(true);
                    } else {
                        String targetSchemaName = sourceSchema;
                        if (!Utility.isCaseSensitive(sourceSchema,
                                mtk.sourceDBType)) {
                            targetSchemaName = Utility.convertToDefaultCase(
                                    targetSchemaName, mtk.targetDBType);
                        }

                        mtk.setTargetSchema(targetSchemaName);
                    }

                    if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                            || (mtk.targetDBType == MTKConstants.DATABASE_TYPE.SRDB)) {
                        if ((mtk.targetSchema.equals("information_schema"))
                                || (mtk.targetSchema.equals("dbo"))
                                || (mtk.targetSchema.equals("sys"))
                                || (mtk.targetSchema.equals("sr_catalog"))) {
                            if (mtk.getGenStats()) {
                                throw new MTKException(
                                        ResourceHandler.getValue(
                                                "ERR_SYSTEM_SCHEMA",
                                                new String[]{mtk.targetDBType
                                                        .getString()}));
                            }
                            failureCount += 1;
                            logMessage(
                                    ResourceHandler.getValue(
                                            "ERR_SYSTEM_SCHEMA",
                                            new String[]{mtk.targetDBType
                                                    .getString()}),
                                    Level.ERROR);

                            continue;
                        }
                    } else if ((mtk.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
                            && (mtk.targetSchema.equals("public"))) {
                        if (mtk.getGenStats()) {
                            throw new MTKException(ResourceHandler.getValue(
                                    "ERR_INVALID_SCHEMA_NAME",
                                    new String[]{mtk.targetSchema,
                                            mtk.targetDBType.getString()}));
                        }
                        failureCount += 1;
                        logMessage(ResourceHandler.getValue(
                                        "ERR_INVALID_SCHEMA_NAME",
                                        new String[]{mtk.targetSchema,
                                                mtk.targetDBType.getString()}),
                                Level.ERROR);

                        continue;
                    }

                    if (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE
                            || mtk.sourceDBType == MTKConstants.DATABASE_TYPE.DB2) {
                        // oracle的schema大写
                        // db2的schema大写
                        mtk.setSourceSchema(sourceSchema.toUpperCase());
                    } else
                        mtk.setSourceSchema(sourceSchema);

                    mtk.initMetaData();
                    // 对目标数据库进行表解析包括表名、每个表的条数等
                    if (mtk.parseOnlyMode) {
                        if ((mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)) {
                            logMessage(ResourceHandler.getValue(
                                    "INFO_PARSE_DB", new String[]{
                                            mtk.sourceDBType.toString(),
                                            mtk.srcDBUser}));
                            // TODO
                            // 扫描并把表名和对应的行数记录到文件 info_tables.txt
                            iuiOperation.pushLogs(mtk.sourceMD.getParseTablesMsg());
                            // 调用专门的解析处理类，将info_tables.txt文件分析。
                            TableParser.parseOra(mtk.sourceMD, iuiOperation);
                        }
                        return;

                    }

                    mtk.importSchema(sourceSchema, copyTableDDL, copyTableData,
                            dropSchema, importTables, importConstraints,
                            importIndexes, importSynonyms, importTriggers,
                            importViews, importSequences, importProcs,
                            importFuncs, importPackages, importDBLinks,
                            importObjectTypes, importRules, truncBeforeLoad,
                            safeMode, importDomains, importPublicSynonyms,
                            importPrivateSynonyms);

                    if (i == 0) {
                        mtk.isfirstSchemaMigrated = true;
                    }
                }
            }
            /****
             *
             *
             *
             *
             */
            if ((schemaList != null)
                    && ((schemaList.length > 1) || (mtk.flagGenStats))) {
                for (int retryIndex = 1; retryIndex <= retryCount; retryIndex++) {
                    for (int i = 0; i < schemaList.length; i++) {
                        if (mtk.summary.getFailedCount(schemaList[i]) <= 0)
                            continue;
                        Utility.getLogger().info("");
                        Utility.getLogger().info(
                                ResourceHandler.getValue(
                                        "INFO_FAILED_OBJECTS_CREATION",
                                        new String[]{
                                                String.valueOf(retryIndex),
                                                schemaList[i]}));

                        String targetSchemaName = schemaList[i];

                        if ((targetSchemaList != null)
                                && (targetSchemaList.length > i)) {
                            targetSchemaName = targetSchemaList[i];

                            if ((mtk.getTargetDBType() == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                                    && (targetSchemaName
                                    .equals(targetSchemaName
                                            .toUpperCase()))) {
                                targetSchemaName = targetSchemaName
                                        .toLowerCase();
                            }

                            mtk.setTargetSchema(targetSchemaName);
                            mtk.setFlagUserSpecifiedTargetSchemaName(true);
                        } else {
                            if (!Utility.isCaseSensitive(sourceSchema,
                                    mtk.sourceDBType)) {
                                targetSchemaName = Utility
                                        .convertToDefaultCase(targetSchemaName,
                                                mtk.targetDBType);
                            }

                            mtk.setTargetSchema(targetSchemaName);
                        }

                        if ((!mtk.offlineMigration)
                                && ((mtk.getTargetDBType() == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (mtk
                                .getTargetDBType() == MTKConstants.DATABASE_TYPE.SRDB))) {
                            mtk.configPGGUCs(targetSchemaName,
                                    mtk.getTargetDBType(), mtk.targetMD);

                            mtk.targetConn.commit();
                        }

                        mtk.copySequences(mtk.summary
                                .getFailedSequences(schemaList[i]));

                        mtk.copyDomains(mtk.summary
                                .getFailedDomains(schemaList[i]));

                        mtk.copyTables(
                                mtk.summary.getFailedTables(schemaList[i]),
                                copyTableDDL, copyTableData, truncBeforeLoad,
                                safeMode, mtk.copyDelimiter);
                        mtk.copyConstraints(mtk.summary
                                .getFailedConstraints(schemaList[i]));

                        mtk.copyIndexes(mtk.summary
                                .getFailedIndexes(schemaList[i]));

                        mtk.copyTriggers(mtk.summary
                                .getFailedTriggers(schemaList[i]));

                        mtk.copyProcedures(mtk.summary
                                .getFailedProcedures(schemaList[i]));

                        mtk.copyFunctions(mtk.summary
                                .getFailedFunctions(schemaList[i]));

                        mtk.copyPackages(mtk.summary
                                .getFailedPackages(schemaList[i]));

                        mtk.copyViews(mtk.summary.getFailedViews(schemaList[i]));
                    }

                    boolean failedObjectFlag = false;
                    for (int i = 0; i < schemaList.length; i++) {
                        if (mtk.summary.getFailedCount(schemaList[i]) > 0) {
                            failedObjectFlag = true;
                            break;
                        }

                    }

                    if (!failedObjectFlag) {
                        failureCount = 0;
                        break;
                    }

                }

            }

            if (schemaList == null)
                mtk.initMetaData();
            if (mtk.isImportAllUsers()) {
                mtk.migrateUsers();
            } else if ((importDefaultUser)
                    && (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)) {
                mtk.setUserNames(new String[]{sourceSchema});
                mtk.migrateUsers();
            }

            if (importGroups) {
                mtk.copyGroups(mtk.groupNames);
            }

            if ((mtk.isImportAllUsers())
                    || ((importDefaultUser) && (mtk.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE))) {
                mtk.migrateGrants();
            }
        } catch (Exception e) {
            failureCount += 1;

            rbParameters = new String[]{e.getMessage()};
            Utility.getLogger().warn(
                    ResourceHandler.getValue("ERR_ERROR_WITH_MESSAGE",
                            rbParameters));
            Utility.getLogger().error("Stack Trace:", e);

            if (mtk.getGenStats()) {
                mtk.setRepStatsProperty("STATUS", "F");
                mtk.setRepStatsProperty("ERROR_MESSAGE", e.getMessage());
            }
        } finally {
            if (mtk.getGenStats()) {
                mtk.saveRepStats();
            }
            mtk.closeConnections();
        }

        Utility.getLogger().info("");

        if ((mtk.summary.getFailedCount() == 0) && (failureCount == 0)
                && (fatalErrorCount == 0)) {
            logMessage(ResourceHandler.getValue(
                    "INFO_MIGRATION_PROCESS_COMPLETED_SUCC", null));
            iuiOperation.pushLogs(ResourceHandler.getValue(
                    "INFO_MIGRATION_PROCESS_COMPLETED_SUCC", null));
        } else {
            logMessage(ResourceHandler.getValue(
                    "INFO_MIGRATION_PROCESS_COMPLETED_FAIL", null));
            iuiOperation.pushLogs(ResourceHandler.getValue(
                    "INFO_MIGRATION_PROCESS_COMPLETED_FAIL", null));
        }

        if (logFile != null) {
            Utility.getLogger().info(
                    "\n"
                            + ResourceHandler.getValue(
                            "INFO_MIGRATION_LOG_LOC",
                            new String[]{logFile}));
        }
        if (!mtk.offlineMigration) {
            String summaryText = mtk.summary.getSummary();

            if ((summaryText != null) && (summaryText.length() > 0))
                Utility.getLogger()
                        .info("\n******************** "
                                + ResourceHandler.getValue(
                                "INFO_MIGRATION_SUMMARY_LABEL", null)
                                + " ********************\n"
                                + summaryText
                                + "\n*************************************************************");
            iuiOperation.pushLogs("\n******************** "
                    + ResourceHandler.getValue(
                    "INFO_MIGRATION_SUMMARY_LABEL", null)
                    + " ********************\n"
                    + summaryText
                    + "\n*************************************************************");
        }
    }

    private static void usage() {
        Utility.getLogger().info("");
        Utility.getLogger().info("SRDB Migration Toolkit (Build Version 1.0)");
        Utility.getLogger().info("");
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_USAGE_OPTIONS", null));
        Utility.getLogger().info("");
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_IF_NO_OPTION_SPECIFIED", null));
        Utility.getLogger().info("");
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_WHERE_OPTIONS_INCLUDED", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_HELP_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_VERSION_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_VERBOSE_SWITCH_INFO", null));
        Utility.getLogger().info("");
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_SCHEMAONLY_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_DATAONLY_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_PARSERONLY_SWITCH_INFO", null));

        Utility.getLogger().info("");

        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_SOURCE_DB_TYPE", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_TARGET_DB_TYPE", null));
        Utility.getLogger().info("");
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_ALLTABLES_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_TABLESLIST_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_CONSTRAINTS_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_INDEXES_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_TRIGGERS_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_ALLVIEWS_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_VIEWS_LIST_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_ALLPROCS_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_PROCS_LIST_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_ALL_FUNCS_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_FUNCS_LIST_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_ALL_PACKAGES_SWITCH_INFO", null));
        Utility.getLogger()
                .info(ResourceHandler.getValue("HLP_PACKAGES_LIST_SWITCH_INFO",
                        null));
        Utility.getLogger()
                .info(ResourceHandler.getValue("HLP_ALL_SEQUENCES_SWITCH_INFO",
                        null));
        Utility.getLogger().info(
                ResourceHandler
                        .getValue("HLP_SEQUENCES_LIST_SWITCH_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_TARGET_SCHEMA_NAME_SWITCH_INFO",
                        null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_ALL_DBLINKS_SWITCH_INFO", null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_ALL_SYNONYMS_SWITCH_INFO", null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_ALL_PUBLIC_SYNONYMS_SWITCH_INFO",
        // null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue(
        // "HLP_ALL_PRIVATE_SYNONYMS_SWITCH_INFO", null));
        Utility.getLogger().info("");
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_DROP_SCHEMA_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_TRUNC_LOAD_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_SAFE_MODE_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_COPY_DELIMIT_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_BATCH_SIZE_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_CP_BATCH_SIZE_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_FETCH_SIZE_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_FILTER_PROP_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_SKIP_FK_CONST_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_SKIP_CK_CONST_INFO", null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_IGNORE_CHECK_CONST_FILTER_INFO",
        // null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_FAST_COPY_INFO", null));
        Utility.getLogger()
                .info(ResourceHandler.getValue("HLP_CUST_COLTYPE_MAPPING_INFO",
                        null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_CUST_COLTYPE_MAPPING_FILE_INFO",
                        null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_OFFLINE_MIGRATION_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_LOG_DIR_INFO", null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_COPY_VIA_DBLINKORA", null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_SINGLE_DATA_FILE_INFO", null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_ALL_USERS", null));
        // Utility.getLogger().info(ResourceHandler.getValue("HLP_USERS",
        // null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_ALL_RULES", null));
        // Utility.getLogger().info(ResourceHandler.getValue("HLP_RULES",
        // null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_ALL_GROUPS", null));
        // Utility.getLogger().info(ResourceHandler.getValue("HLP_GROUPS",
        // null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_ALL_DOMAINS", null));
        // Utility.getLogger().info(ResourceHandler.getValue("HLP_DOMAINS",
        // null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_OBJECTTYPES_INFO", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_REPLACE_NULL_CHAR", null));
        // Utility.getLogger()
        // .info(ResourceHandler.getValue("HLP_IMPORT_PARTITION_AS_TABLE",
        // null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_ENABLE_CONST_BEFORE_DATALOAD",
                        null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_CHECK_FUNC_BODIES", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_RETRY_COUNT_INFO", null));
        // Utility.getLogger().info(ResourceHandler.getValue("HLP_ANALYZE",
        // null));
        // Utility.getLogger().info(
        // ResourceHandler.getValue("HLP_VACUUM_ANALYZE", null));
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_LOADER_THREAD_COUNT_INFO", null));
        Utility.getLogger().info("");
        Utility.getLogger().info(
                ResourceHandler.getValue("HLP_DB_CONNECTION_INFO", null));
        Utility.getLogger().info(
                ResourceHandler
                        .getValue("HLP_DB_CONNECTION_INFO_DETAILS", null));
        Utility.getLogger().info("");
    }

    private static boolean validateOptions(CLParser clParser,
                                           boolean useMultipleSchemas) {
        boolean invalidFlag = false;

        if ((useMultipleSchemas)
                && ((clParser.hasOption("tables"))
                || (clParser.hasOption("views"))
                || (clParser.hasOption("sequences"))
                || (clParser.hasOption("procs"))
                || (clParser.hasOption("funcs"))
                || (clParser.hasOption("packages")) || (clParser
                .hasOption("synonyms")))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_LIST_MULTIPLE_SCHEMAS", null));
            return false;
        }

        for (Enumeration e = clParser.getOptionNames(); e.hasMoreElements(); ) {
            String optionName = (String) e.nextElement();

            if (isKeyValueOption(optionName)) {
                if ((!optionName.equalsIgnoreCase("offlineMigration"))
                        && (!optionName.equalsIgnoreCase("allDBLinks"))
                        && (!optionName
                        .equalsIgnoreCase("importPartitionAsTable"))) {
                    if ((clParser.getOption(optionName) == null)
                            || (clParser.getOption(optionName)
                            .equalsIgnoreCase(""))) {
                        invalidFlag = true;
                        break;
                    }
                }

                String optionValue = clParser.getOption(optionName);

                if ((optionName.equalsIgnoreCase("verbose"))
                        && (!optionValue.equalsIgnoreCase("on"))
                        && (!optionValue.equalsIgnoreCase("off"))) {
                    invalidFlag = true;
                    break;
                }

                if ((optionName.equalsIgnoreCase("offlineMigration"))
                        && (optionValue != null)
                        && (!optionValue.trim().equalsIgnoreCase(""))) {
                    if (new File(optionValue).exists()) {
                        offlineMigrationPath = optionValue;
                    } else {
                        System.out.println(ResourceHandler.getValue(
                                "WARN_OFFLINE_PATH_NOT_FOUND",
                                new String[]{optionValue}));
                    }
                }

                if ((optionName.equalsIgnoreCase("allDBLinks"))
                        && (optionValue != null)
                        && (!optionValue.trim().equalsIgnoreCase(""))) {
                    dblinkPasswords = optionValue;
                }

                if ((optionName.equalsIgnoreCase("importPartitionAsTable"))
                        && (optionValue != null)
                        && (!optionValue.trim().equalsIgnoreCase(""))) {
                    String[] arrTmp = optionValue.split(",");

                    if (partitionTableList == null)
                        partitionTableList = new ArrayList();
                    else {
                        partitionTableList.clear();
                    }

                    for (int i = 0; i < arrTmp.length; i++) {
                        partitionTableList.add(arrTmp[i]);
                    }
                }

                if ((optionName.equalsIgnoreCase("escapeTabDelimiter"))
                        && (!optionValue.equalsIgnoreCase("true"))
                        && (!optionValue.equalsIgnoreCase("false"))) {
                    invalidFlag = true;
                    break;
                }

                if ((optionName.equalsIgnoreCase("dropSchema"))
                        && (!optionValue.equalsIgnoreCase("true"))
                        && (!optionValue.equalsIgnoreCase("false"))) {
                    invalidFlag = true;
                    break;
                }

                if ((optionName.equalsIgnoreCase("copyDelimiter"))
                        && (optionValue.length() > 1)
                        && (!isEscapeCharacter(optionValue))) {
                    System.out.println("");
                    System.out.println(ResourceHandler.getValue(
                            "ERR_COPY_DELIMIT_MUST_BE_A_SINGLE_CHAR", null));
                    invalidFlag = true;
                    break;
                }

                if (optionName.equalsIgnoreCase("batchSize")) {
                    try {
                        int bSize = Integer.parseInt(optionValue);
                        if ((bSize > 50000) || (bSize < 1)) {
                            System.out.println(ResourceHandler.getValue(
                                    "ERR_BATCH_SIZE_RANGE", null));
                            invalidFlag = true;
                            break;
                        }
                        batchSize = bSize;
                    } catch (NumberFormatException ex) {
                        System.out.println(ResourceHandler.getValue(
                                "ERR_INVALID_NUMBER_FOR_BATCH_SIZE", null));
                        invalidFlag = true;
                        break;
                    }
                }

                if (optionName.equalsIgnoreCase("cpBatchSize")) {
                    try {
                        int cpBsize = Integer.parseInt(optionValue);
                        if (cpBsize <= 0) {
                            System.out.println(ResourceHandler.getValue(
                                    "ERR_INVALID_COPY_BATCH_SIZE", null));
                            invalidFlag = true;
                            break;
                        }
                        cpBatchSize = cpBsize;
                    } catch (NumberFormatException ex) {
                        System.out
                                .println(ResourceHandler
                                        .getValue(
                                                "ERR_INVALID_NUMBER_FOR_COPY_BATCH_SIZE",
                                                null));
                        invalidFlag = true;
                        break;
                    }

                }

                if (optionName.equalsIgnoreCase("lobBatchSize")) {
                    try {
                        int bSize = Integer.parseInt(optionValue);
                        if ((bSize > 50000) || (bSize < 1)) {
                            System.out.println(ResourceHandler.getValue(
                                    "ERR_BATCH_SIZE_RANGE", null));
                            invalidFlag = true;
                            break;
                        }
                        lobBatchSize = bSize;
                    } catch (NumberFormatException ex) {
                        System.out.println(ResourceHandler.getValue(
                                "ERR_INVALID_NUMBER_FOR_BATCH_SIZE", null));
                        invalidFlag = true;
                        break;
                    }

                }

                if (optionName.equalsIgnoreCase("fetchSize")) {
                    try {
                        int fetchSize1 = Integer.parseInt(optionValue);
                        if (fetchSize1 <= 0) {
                            System.out.println(ResourceHandler.getValue(
                                    "ERR_INVALID_FETCH_SIZE", null));
                            invalidFlag = true;
                            break;
                        }
                        fetchSize = fetchSize1;
                    } catch (NumberFormatException ex) {
                        System.out.println(ResourceHandler.getValue(
                                "ERR_INVALID_NUMBER_FOR_FETCH_SIZE", null));
                        invalidFlag = true;
                        break;
                    }

                }

                if (optionName.equalsIgnoreCase("retryCount")) {
                    try {
                        int tempSize = Integer.parseInt(optionValue);
                        if (tempSize <= 0) {
                            System.out.println(ResourceHandler.getValue(
                                    "ERR_INVALID_RETRY_COUNT", null));
                            invalidFlag = true;
                            break;
                        }
                        retryCount = tempSize;
                    } catch (NumberFormatException ex) {
                        System.out.println(ResourceHandler.getValue(
                                "ERR_INVALID_NUMBER_FOR_RETRY_COUNT", null));
                        invalidFlag = true;
                        break;
                    }
                }

                if (optionName.equalsIgnoreCase("loaderCount")) {
                    try {
                        int tempCount = Integer.parseInt(optionValue);
                        if (tempCount <= 0) {
                            System.out.println(ResourceHandler.getValue(
                                    "ERR_INVALID_LOADER_THREAD_COUNT", null));
                            invalidFlag = true;
                            break;
                        }
                        dataLoadThreadCount = tempCount;
                    } catch (NumberFormatException ex) {
                        System.out.println(ResourceHandler.getValue(
                                "ERR_INVALID_NUMBER_FOR_LOADER_THREAD_COUNT",
                                null));
                        invalidFlag = true;
                        break;
                    }
                }

            } else if ((!optionName.equalsIgnoreCase("allFuncs"))
                    && (!optionName.equalsIgnoreCase("allPackages"))
                    && (!optionName.equalsIgnoreCase("allProcs"))
                    && (!optionName.equalsIgnoreCase("allSequences"))
                    && (!optionName.equalsIgnoreCase("allTables"))
                    && (!optionName.equalsIgnoreCase("allViews"))
                    && (!optionName.equalsIgnoreCase("constraints"))
                    && (!optionName.equalsIgnoreCase("dataOnly"))
                    && (!optionName.equalsIgnoreCase("help"))
                    && (!optionName.equalsIgnoreCase("indexes"))
                    && (!optionName.equalsIgnoreCase("schemaOnly"))
                    && (!optionName.equalsIgnoreCase("parseOnly"))
                    && (!optionName.equalsIgnoreCase("version"))
                    && (!optionName.equalsIgnoreCase("triggers"))
                    && (!optionName.equalsIgnoreCase("truncLoad"))
                    && (!optionName.equalsIgnoreCase("safeMode"))
                    && (!optionName.equalsIgnoreCase("genStats"))
                    && (!optionName.equalsIgnoreCase("singleDataFile"))
                    && (!optionName.equalsIgnoreCase("oraTxLevelSerializable"))
                    && (!optionName.equalsIgnoreCase("allSynonyms"))
                    && (!optionName.equalsIgnoreCase("vacuumAnalyze"))
                    && (!optionName.equalsIgnoreCase("allPublicSynonyms"))
                    && (!optionName.equalsIgnoreCase("allPrivateSynonyms"))
                    && (!optionName.equalsIgnoreCase("exitOnError"))
                    && (!optionName.equalsIgnoreCase("importViewAsTable"))
                    && (!optionName.equalsIgnoreCase("analyze"))
                    && (!optionName.equalsIgnoreCase("skipFKConst"))
                    && (!optionName.equalsIgnoreCase("skipCKConst"))
                    && (!optionName.equalsIgnoreCase("useOraPartitionSyntax"))
                    && (!optionName.equalsIgnoreCase("fastCopy"))
                    && (!optionName.equalsIgnoreCase("skipColDefaultClause"))
                    && (!optionName.equalsIgnoreCase("allUsers"))
                    && (!optionName.equalsIgnoreCase("offlineMigration"))
                    && (!optionName.equalsIgnoreCase("copyViaDBLinkOra"))
                    && (!optionName.equalsIgnoreCase("allSchemas"))
                    && (!optionName.equalsIgnoreCase("objecttypes"))
                    && (!optionName.equalsIgnoreCase("ignoreCheckConstFilter"))
                    && (!optionName
                    .equalsIgnoreCase("enableConstBeforeDataLoad"))
                    && (!optionName.equalsIgnoreCase("allRules"))
                    && (!optionName.equalsIgnoreCase("allGroups"))
                    && (!optionName.equalsIgnoreCase("allDomains"))) {
                invalidFlag = true;
                break;
            }
        }

        if (invalidFlag) {
            System.out.println("");
            System.out.println(ResourceHandler.getValue(
                    "ERR_INVALID_COMMAND_LINE_ARG", null));
            return false;
        }

        if ((clParser.hasOption("schemaOnly"))
                && (clParser.hasOption("dataOnly"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_SCHEMA_ONLY_AND_DATA_ONLY_MODES", null));
            return false;
        }

        if ((clParser.hasOption("escapeTabDelimiter"))
                && (clParser.hasOption("copyDelimiter"))
                && (!clParser.getOption("copyDelimiter").equals("\t"))
                && (clParser.getOption("escapeTabDelimiter")
                .equalsIgnoreCase("true"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_TAB_DELIMIT_WITHOUT_TAB_COPY_DELIMIT", null));
            return false;
        }

        if ((clParser.hasOption("truncLoad"))
                && (!clParser.hasOption("dataOnly"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_TRUNC_LOAD_WITHOUT_DATAONLY", null));
            return false;
        }

        if ((clParser.hasOption("dataOnly")) && (hasSchemaDDLOptions(clParser))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_DATAONLY_ONLY_WITH_ALL_TABLES", null));
            return false;
        }

        if (((clParser.hasOption("constraints"))
                || (clParser.hasOption("indexes")) || (clParser
                .hasOption("triggers")))
                && (!clParser.hasOption("allTables"))
                && (!clParser.hasOption("tables"))) {
            rbParameters = new String[]{"constraints", "indexes", "triggers"};
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_CONST_INDEXES_TRIG_WITH_PART_SCHEMA", rbParameters));
            return false;
        }

        if ((clParser.hasOption("vacuumAnalyze"))
                && (clParser.hasOption("analyze"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_VACUMEANALYZE_WITH_ANAYLYZE_MODE", null));
            return false;
        }

        if ((clParser.hasOption("skipFKConst"))
                && (!clParser.hasOption("constraints"))
                && (!clParser.hasOption("genStats"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_SKIPFKCONST_WITH_CONSTRAINTS", null));
            return false;
        }

        if ((clParser.hasOption("skipCKConst"))
                && (!clParser.hasOption("constraints"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_SKIPCKCONST_WITH_CONSTRAINTS", null));
            return false;
        }

        if ((clParser.hasOption("enableConstBeforeDataLoad"))
                && (!clParser.hasOption("truncLoad"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_ENABLECONSTBEFOREDATALOAD_WITH_TRUNCLOAD", null));
            return false;
        }

        if ((clParser.hasOption("ignoreCheckConstFilter"))
                && (!clParser.hasOption("constraints"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_IGNORECHECKCONSTFILTER_WITH_CONSTRAINTS", null));
            return false;
        }

        if ((clParser.hasOption("fastCopy"))
                && (clParser.hasOption("schemaOnly"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_FASTCOPY_WITH_SCHEMAONLY", null));
            return false;
        }

        if ((clParser.hasOption("skipColDefaultClause"))
                && (clParser.hasOption("dataOnly"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_SKIP_COL_DEF_CLAUSE_WITH_DATAONLY", null));
            return false;
        }

        if ((clParser.hasOption("replaceNullChar"))
                && (clParser.hasOption("schemaOnly"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_OPT_REPLACE_NULL_CHAR_INVALID_CONTEXT", null));
            return false;
        }

        if ((clParser.hasOption("customColTypeMapping"))
                && (clParser.hasOption("customColTypeMappingFile"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERR_CUST_COL_TYPE_MAP_WITH_CUST_COL_TYPE_MAP_FILE", null));
            return false;
        }

        if ((clParser.hasOption("singleDataFile"))
                && (!clParser.hasOption("safeMode"))) {
            logMessageToSystemOut(ResourceHandler.getValue(
                    "ERROR_SINGLE_FILE_IN_COPY_MODE", null));
            return false;
        }

        defaultDateTime = null;
        if (clParser.hasOption("defaultDateTime")) {
            String value = clParser.getOption("defaultDateTime");
            Date date = null;
            try {
                date = DATETIME_FORMAT.parse(value);
                defaultDateTime = DATETIME_FORMAT.format(date);
            } catch (Exception exp) {
            }
            if (defaultDateTime == null) {
                try {
                    date = DATE_FORMAT.parse(value);
                    defaultDateTime = DATE_FORMAT.format(date);
                } catch (Exception exp) {
                    logMessageToSystemOut(ResourceHandler.getValue(
                            "ERR_DEF_DATETIME_FORMAT", null));
                    return false;
                }
            }
        }

        return true;
    }

    private static boolean isKeyValueOption(String optionName) {
        return (optionName.equalsIgnoreCase("dropSchema"))
                || (optionName.equalsIgnoreCase("funcs"))
                || (optionName.equalsIgnoreCase("packages"))
                || (optionName.equalsIgnoreCase("procs"))
                || (optionName.equalsIgnoreCase("sequences"))
                || (optionName.equalsIgnoreCase("tables"))
                || (optionName.equalsIgnoreCase("views"))
                || (optionName.equalsIgnoreCase("verbose"))
                || (optionName.equalsIgnoreCase("edbhost"))
                || (optionName.equalsIgnoreCase("orahost"))
                || (optionName.equalsIgnoreCase("edbuser"))
                || (optionName.equalsIgnoreCase("orauser"))
                || (optionName.equalsIgnoreCase("edbpass"))
                || (optionName.equalsIgnoreCase("orapass"))
                || (optionName.equalsIgnoreCase("srcdburl"))
                || (optionName.equalsIgnoreCase("targetdburl"))
                || (optionName.equalsIgnoreCase("srcuser"))
                || (optionName.equalsIgnoreCase("targetuser"))
                || (optionName.equalsIgnoreCase("srcpass"))
                || (optionName.equalsIgnoreCase("targetpass"))
                || (optionName.equalsIgnoreCase("targetSchema"))
                || (optionName.equalsIgnoreCase("filterProp"))
                || (optionName.equalsIgnoreCase("copyDelimiter"))
                || (optionName.equalsIgnoreCase("batchSize"))
                || (optionName.equalsIgnoreCase("cpBatchSize"))
                || (optionName.equalsIgnoreCase("synonyms"))
                || (optionName.equalsIgnoreCase("statsFile"))
                || (optionName.equalsIgnoreCase("sourceDBType"))
                || (optionName.equalsIgnoreCase("targetDBType"))
                || (optionName.equalsIgnoreCase("customColTypeMapping"))
                || (optionName.equalsIgnoreCase("customColTypeMappingFile"))
                || (optionName.equalsIgnoreCase("defaultDateTime"))
                || (optionName.equalsIgnoreCase("escapeTabDelimiter"))
                || (optionName.equalsIgnoreCase("fetchSize"))
                || (optionName.equalsIgnoreCase("replaceNullChar"))
                || (optionName.equalsIgnoreCase("offlineMigration"))
                || (optionName.equalsIgnoreCase("logDir"))
                || (optionName.equalsIgnoreCase("Users"))
                || (optionName.equalsIgnoreCase("nzOptions"))
                || (optionName.equalsIgnoreCase("allDBLinks"))
                || (optionName.equalsIgnoreCase("importPartitionAsTable"))
                || (optionName.equalsIgnoreCase("rules"))
                || (optionName.equalsIgnoreCase("groups"))
                || (optionName.equalsIgnoreCase("domains"))
                || (optionName.equalsIgnoreCase("checkFunctionBodies"))
                || (optionName.equalsIgnoreCase("retryCount"))
                || (optionName.equalsIgnoreCase("loaderCount"))
                || (optionName.equalsIgnoreCase("columnsFilterProp"))
                || (optionName.equalsIgnoreCase("lobBatchSize"))
                || (optionName.equalsIgnoreCase("replicationMode"));
    }

    private static boolean hasSchemaDDLOptions(CLParser clParser) {
        return (clParser.hasOption("dropSchema"))
                || (clParser.hasOption("constraints"))
                || (clParser.hasOption("indexes"))
                || (clParser.hasOption("triggers"))
                || (clParser.hasOption("allProcs"))
                || (clParser.hasOption("procs"))
                || (clParser.hasOption("allFuncs"))
                || (clParser.hasOption("funcs"))
                || (clParser.hasOption("allPackages"))
                || (clParser.hasOption("packages"))
                || (clParser.hasOption("allSequences"))
                || (clParser.hasOption("sequences"))
                || (clParser.hasOption("allViews"))
                || (clParser.hasOption("views"))
                || (clParser.hasOption("synonyms"))
                || (clParser.hasOption("allSynonyms"))
                || (clParser.hasOption("allPublicSynonyms"))
                || (clParser.hasOption("allPrivateSynonyms"))
                || (clParser.hasOption("objecttypes"));
    }

    private static void logMessageToSystemOut(String msg) {
        if (VERBOSE)
            System.out.println(msg);
    }

    protected static void logMessage(String msg, Level messageLevel) {
       // System.out.println("??????????????" + msg);
        iuiOperation.pushLogs(msg);
        if ((messageLevel == Level.ERROR) || (messageLevel == Level.FATAL)) {
            lastErrorMessage = msg;
        }

        if (VERBOSE)
            Utility.getLogger().info(msg);
    }

    protected static void logMessage(String msg) {
        logMessage(msg, Level.INFO);
    }

    protected MigrationToolkit() {
        this.mtkFactory = new MTKFactory();
    }

    public void setTableNames(String[] tableNames) {
        this.tableNames = tableNames;
    }

    public void setRuleNames(String[] ruleNames) {
        this.ruleNames = ruleNames;
    }

    public void setGroupNames(String[] groupNames) {
        this.groupNames = groupNames;
    }

    public void setDomainNames(String[] domainNames) {
        this.domainNames = domainNames;
    }

    public void setViewNames(String[] viewNames) {
        this.viewNames = viewNames;
    }

    public void setSynonymNames(String[] synonymNames) {
        this.synonymNames = synonymNames;
    }

    public void setSequenceNames(String[] sequenceNames) {
        this.sequenceNames = sequenceNames;
    }

    public void setProcNames(String[] procNames) {
        this.procNames = procNames;
    }

    public void setFuncNames(String[] funcNames) {
        this.funcNames = funcNames;
    }

    public void setPackageNames(String[] packageNames) {
        this.packageNames = packageNames;
    }

    public void setSourceSchema(String sourceSchema) {
        this.sourceSchema = sourceSchema;
    }

    public void setTargetSchema(String targetSchema) {
        this.targetSchema = targetSchema;
    }

    public void setFilterProp(Properties filterProp) {
        this.filterProp = filterProp;
    }

    public void setColumnFilterProp(Properties colFilterProp) {
        this.columnsFilterProp = colFilterProp;
    }

    public void setGenStats(boolean flag) {
        this.flagGenStats = flag;
    }

    public void setStatsFileName(String statsFileName) {
        this.statsFileName = statsFileName;
    }

    public boolean getGenStats() {
        return this.flagGenStats;
    }

    public void initRepStats() {
        this.propRepStats = new Properties();
        this.propRepStats.setProperty("START_TIME",
                Utility.formatDate(new Date(), null));
    }

    public void saveRepStats() {
        try {
            Utility.saveProperties(this.propRepStats,
                    "Migration Toolkit Snapshot Statistics", this.statsFileName);
        } catch (Exception e) {
        }
    }

    public void setOraTxLevelSerializable() {
        this.flagOraTxLevelSerializable = true;
    }

    public void setVacuumAnalyze(boolean flagVacuumAnalyze) {
        this.flagVacuumAnalyze = flagVacuumAnalyze;
    }

    public void setAnalyze(boolean flagAnalyze) {
        this.flagAnalyze = flagAnalyze;
    }

    public void setExitOnError(boolean flagExitOnError) {
        this.flagExitOnError = flagExitOnError;
    }

    public void setRepStatsProperty(String propName, String propValue) {
        this.propRepStats.setProperty(propName, propValue);
    }

    public void setImportViewAsTable() {
        this.flagImportViewAsTable = true;
    }

    public MTKConstants.DATABASE_TYPE getSourceDBType() {
        return this.sourceDBType;
    }

    public MTKConstants.DATABASE_TYPE getTargetDBType() {
        return this.targetDBType;
    }

    public boolean isTargetDBInPPASPGMode() throws SQLException {
        return ((this.targetConn instanceof EnterpriseDBConnection))
                && (!((EnterpriseDBConnection) this.targetConn).isRedwoodMode());
    }

    public void setSourceDBType(String sourceDBType) throws MTKException {
        if (sourceDBType.equalsIgnoreCase("ORACLE")) {
            this.sourceDBType = MTKConstants.DATABASE_TYPE.ORACLE;
        } else if ((sourceDBType.equalsIgnoreCase("POSTGRES"))
                || (sourceDBType.equalsIgnoreCase("SRDB"))) {
            this.sourceDBType = MTKConstants.DATABASE_TYPE.SRDB;
        } else if (sourceDBType.equalsIgnoreCase("ENTERPRISEDB")) {
            this.sourceDBType = MTKConstants.DATABASE_TYPE.ENTERPRISEDB;
        } else if (sourceDBType.equalsIgnoreCase("DB2")) {
            this.sourceDBType = MTKConstants.DATABASE_TYPE.DB2;
        } else if (sourceDBType.equalsIgnoreCase("SQLSERVER")) {
            this.sourceDBType = MTKConstants.DATABASE_TYPE.SQLSERVER;
        } else if (sourceDBType.equalsIgnoreCase("SYBASE")) {
            this.sourceDBType = MTKConstants.DATABASE_TYPE.SYBASE;
        } else if (sourceDBType.equalsIgnoreCase("MYSQL")) {
            this.sourceDBType = MTKConstants.DATABASE_TYPE.MYSQL;
        } else {
            fatalErrorCount += 1;
            throw new MTKException(
                    "The '"
                            + sourceDBType
                            + "' database type is not supported by Migration Toolkit.\nSpecify a valid database type string i.e. EnterpriseDB, Postgres, Oracle, SQLServer, Sybase or MySQL.");
        }
    }

    public void setTargetDBType(String targetDBType) throws MTKException {
        if (targetDBType.equalsIgnoreCase("ENTERPRISEDB")) {
            this.targetDBType = MTKConstants.DATABASE_TYPE.ENTERPRISEDB;
        } else if ((targetDBType.equalsIgnoreCase("POSTGRES"))
                || (targetDBType.equalsIgnoreCase("SRDB"))) {
            this.targetDBType = MTKConstants.DATABASE_TYPE.SRDB;
        } else if (targetDBType.equalsIgnoreCase("ORACLE")) {
            this.targetDBType = MTKConstants.DATABASE_TYPE.ORACLE;
        } else if (targetDBType.equalsIgnoreCase("SQLSERVER")) {
            this.targetDBType = MTKConstants.DATABASE_TYPE.SQLSERVER;
        } else if (targetDBType.equalsIgnoreCase("SYBASE")) {
            this.targetDBType = MTKConstants.DATABASE_TYPE.SYBASE;
        } else if (targetDBType.equalsIgnoreCase("MYSQL")) {
            this.targetDBType = MTKConstants.DATABASE_TYPE.MYSQL;
        } else if (targetDBType.equalsIgnoreCase("NPS")) {
            this.targetDBType = MTKConstants.DATABASE_TYPE.NPS;
        } else {
            fatalErrorCount += 1;
            throw new MTKException(
                    "The '"
                            + targetDBType
                            + "' database type is not supported by Migration Toolkit.\nSpecify a valid database type string i.e. EnterpriseDB, Postgres, Oracle, SQLServer, Sybase or MySQL.");
        }
    }

    public void setSkipFKConst(boolean flagSkipFKConst) {
        this.flagSkipFKConst = flagSkipFKConst;
    }

    public void setSkipCKConst(boolean flagSkipCKConst) {
        this.flagSkipCKConst = flagSkipCKConst;
    }

    public void setReplicationMode(String replicationMode) {
        this.replicationMode = replicationMode;
    }

    public void setEnableConstBeforeDataLoad(boolean enableConstBeforeDataLoad) {
        this.enableConstBeforeDataLoad = enableConstBeforeDataLoad;
    }

    public static void setIgnoreCheckConstFilter(
            boolean flagIgnoreCheckConstFilter) {
        flagIgnoreCheckConstFilter = flagIgnoreCheckConstFilter;
    }

    public void setOfflineMigration(boolean offlineMigration) {
        this.offlineMigration = offlineMigration;

        if (offlineMigrationPath != null)
            MTKMetaData.offlineMigrationSchemaDDLFilePath = offlineMigrationPath;
        else
            MTKMetaData.offlineMigrationSchemaDDLFilePath = System
                    .getProperty("user.home");
    }

    public void setFastCopy(boolean fastCopy) {
        this.flagFastCopy = fastCopy;
    }

    public boolean initCustomColTypeMapping(String[] arrCustomColTypeMapping) {
        if (arrCustomColTypeMapping.length == 0) {
            return false;
        }

        if (this.customColTypeMapping == null) {
            this.customColTypeMapping = new HashMap();
        } else {
            this.customColTypeMapping.clear();
        }

        for (int i = 0; i < arrCustomColTypeMapping.length; i++) {
            String[] colNameTypePair = arrCustomColTypeMapping[i].split("=");

            if (colNameTypePair.length == 2) {
                this.customColTypeMapping.put(colNameTypePair[0],
                        colNameTypePair[1]);
            } else {
                this.customColTypeMapping.clear();
                return false;
            }

        }

        return true;
    }

    public boolean initCustomColTypeMapping(String customColTypeMappingFile) {
        Properties customColTypeMappingProp = new Properties();
        try {
            customColTypeMappingProp.load(new FileInputStream(
                    customColTypeMappingFile));
        } catch (Exception e) {
            rbParameters = new String[]{e.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CUSTOM_TYPE_MAP_FLE_LOAD",
                    rbParameters));
            return false;
        }

        if (this.customColTypeMapping == null) {
            this.customColTypeMapping = new HashMap();
        } else {
            this.customColTypeMapping.clear();
        }

        String colName = null;
        String colType = null;

        for (Enumeration e = customColTypeMappingProp.propertyNames(); e
                .hasMoreElements(); ) {
            colName = (String) e.nextElement();
            colType = customColTypeMappingProp.getProperty(colName);
            if ((colType == null) || (colType.equals(""))) {
                logMessage(ResourceHandler.getValue(
                        "ERR_INVALID_ENTRY_IN_CUST_TYPE_MAP_FILE", null));
                this.customColTypeMapping.clear();
                return false;
            }

            this.customColTypeMapping.put(colName, colType);
        }

        if (this.customColTypeMapping.isEmpty()) {
            logMessage(ResourceHandler
                    .getValue("ERR_EMPTY_MAAPPING_FILE", null));
            return false;
        }

        return true;
    }

    public void readPropFile(String propFile) throws Exception {
        try {
            if (propFile != null) {
                Properties ini = new Properties();
                System.out.println(this.getClass().getResource("/").getPath());
                ini.load(new FileInputStream(this.getClass().getResource("/").getPath() + propFile));

                this.srcDBURL = ini.getProperty("RedwoodConnection");
                this.srcDBUser = ini.getProperty("RedwoodUser");
                this.srcDBPassword = ini.getProperty("RedwoodPassword");
                this.targetDBURL = ini.getProperty("EDBConnection");
                this.targetDBUser = ini.getProperty("EDBUser");
                this.targetDBPassword = ini.getProperty("EDBPassword");

                if ((this.srcDBURL == null) || (this.srcDBUser == null)
                        || (this.srcDBPassword == null)
                        || (this.targetDBURL == null)
                        || (this.targetDBUser == null)
                        || (this.targetDBPassword == null)) {
                    this.srcDBURL = ini.getProperty("SRC_DB_URL");
                    this.srcDBUser = ini.getProperty("SRC_DB_USER");
                    this.srcDBPassword = ini.getProperty("SRC_DB_PASSWORD");
                    this.targetDBURL = ini.getProperty("TARGET_DB_URL");
                    this.targetDBUser = ini.getProperty("TARGET_DB_USER");
                    this.targetDBPassword = ini
                            .getProperty("TARGET_DB_PASSWORD");
                }
            }
            logMessage(ResourceHandler.getValue("INFO_SRC_DB_CONNECT_INFO",
                    null));
            rbParameters = new String[]{this.srcDBURL};
            logMessage(ResourceHandler.getValue("INFO_DB_URL", rbParameters));
            rbParameters = new String[]{this.srcDBUser};
            logMessage(ResourceHandler.getValue("INFO_DB_USER", rbParameters));
            logMessage(ResourceHandler.getValue("INFO_DB_PASS", null));

            if (!this.offlineMigration) {
                logMessage(ResourceHandler.getValue(
                        "INFO_TARGET_DB_CONNECT_INFO", null));
                rbParameters = new String[]{this.targetDBURL};
                logMessage(ResourceHandler
                        .getValue("INFO_DB_URL", rbParameters));
                rbParameters = new String[]{this.targetDBUser};
                logMessage(ResourceHandler.getValue("INFO_DB_USER",
                        rbParameters));
                logMessage(ResourceHandler.getValue("INFO_DB_PASS", null));
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e.getMessage());
        }
    }

    public void setSourceDBConnInfo(String url, String userName, String password) {
        this.srcDBURL = url;
        this.srcDBUser = userName.toUpperCase();
        this.srcDBPassword = password;
    }

    public void setTargetDBConnInfo(String url, String userName, String password) {
        this.targetDBURL = url;
        this.targetDBUser = userName;
        this.targetDBPassword = password;
    }

    protected void configPGGUCs(String schemaName,
                                MTKConstants.DATABASE_TYPE dbType, MTKMetaData targetMD)
            throws SQLException {
        String searchPath = "SET search_path="
                + (Utility.isCaseSensitive(schemaName, dbType) ? "\""
                + schemaName + "\"" : schemaName) + ",\"$user\"";
        try {
            targetMD.executeScript(searchPath + ",public" + " \n");
        } catch (SQLException sqle) {
            if ((sqle.getSQLState().equalsIgnoreCase("3F000"))
                    || (sqle.getSQLState().equalsIgnoreCase("22023")))
                targetMD.executeScript(searchPath + " \n");
            else {
                throw sqle;
            }
        }

        if (!this.flagCheckFunctionBodies)
            targetMD.executeScript("SET check_function_bodies = false");
    }

    private void initToolkit(String propFile) throws SQLException {
        try {
            readPropFile(propFile);

            if ((this.srcDBURL == null) || (this.srcDBUser == null)) {
                throw new SQLException(ResourceHandler.getValue(
                        "ERR_SRC_DB_CONN_NOT_FOUND", null));
            }

            if (((this.targetDBURL == null) || (this.targetDBUser == null))
                    && (!this.offlineMigration)) {
                throw new SQLException(ResourceHandler.getValue(
                        "ERR_DEST_DB_CONN_NOT_FOUND", null));
            }

            logMessage(ResourceHandler.getValue("INFO_SRC_DB_OPEN_CONNECTION",
                    new String[]{this.sourceDBType.getString()}));

            this.srcConn = createNewSourceConnection();

            if (this.srcConn.getConnection() == null) {
                throw new MTKException(
                        "The URL specified for the source database is invalid.\nCheck the connectivity credentials.");
            }

            if (this.flagOraTxLevelSerializable) {
                this.srcConn.setTransactionIsolationLevel(8);
            }
            if (!this.offlineMigration) {
                logMessage(ResourceHandler.getValue(
                        "INFO_TARGET_DB_OPEN_CONNECTION",
                        new String[]{this.targetDBType.getString()}));
                this.targetConn = createNewTargetConnection();
                if (this.targetConn.getConnection() == null)
                    throw new MTKException(
                            "The URL specified for the target database is invalid.\nCheck the connectivity credentials.");
            }
        } catch (SQLException se) {
            se.printStackTrace();
            fatalErrorCount += 1;
            throw se;
        } catch (Exception e) {
            fatalErrorCount += 1;
            e.printStackTrace();
            throw new SQLException(e.getMessage());
        }
    }

    private void initToolkitWithoutPropFile() throws SQLException {
        try {
            if ((this.srcDBURL == null) || (this.srcDBUser == null)) {
                throw new SQLException(ResourceHandler.getValue(
                        "ERR_SRC_DB_CONN_NOT_FOUND", null));
            }

            if (((this.targetDBURL == null) || (this.targetDBUser == null))
                    && (!this.offlineMigration)) {
                throw new SQLException(ResourceHandler.getValue(
                        "ERR_DEST_DB_CONN_NOT_FOUND", null));
            }

            logMessage(ResourceHandler.getValue("INFO_SRC_DB_OPEN_CONNECTION",
                    new String[]{this.sourceDBType.getString()}));

            this.srcConn = createNewSourceConnection();

            if (this.srcConn.getConnection() == null) {
                throw new MTKException(
                        "The URL specified for the source database is invalid.\nCheck the connectivity credentials.");
            }

            if (this.flagOraTxLevelSerializable) {
                this.srcConn.setTransactionIsolationLevel(8);
            }
            if (!this.offlineMigration) {
                logMessage(ResourceHandler.getValue(
                        "INFO_TARGET_DB_OPEN_CONNECTION",
                        new String[]{this.targetDBType.getString()}));
                this.targetConn = createNewTargetConnection();
                if (this.targetConn.getConnection() == null)
                    throw new MTKException(
                            "The URL specified for the target database is invalid.\nCheck the connectivity credentials.");
            }
        } catch (SQLException se) {
            fatalErrorCount += 1;
            throw se;
        } catch (Exception e) {
            fatalErrorCount += 1;
            e.printStackTrace();
            throw new SQLException(e.getMessage());
        }
    }

    public void initMetaData() throws SQLException {
        try {
            this.sourceMD = createSourceMetaData(this.srcConn);
            this.targetMD = createTargetMetaData(this.targetConn);


            this.tddl = this.mtkFactory.createMTKTransformDDL(
                    this.sourceDBType, this.targetDBType);
            if ((sourceToTargetMappings != null)
                    && (sourceToTargetMappings.size() > 0)) {
                this.tddl.setSourceToTargetNames(sourceToTargetMappings);
            }
            this.tddl.setDefaultDateTime(defaultDateTime);

            if ((this.customColTypeMapping != null)
                    && (this.customColTypeMapping.size() > 0)) {
                this.tddl.setCustomColTypeMapping(this.customColTypeMapping);
            }

            this.sourceMD.setSchema(this.sourceSchema, false);
            this.targetMD.setSchema(this.targetSchema, false);

            if ((this.columnsFilterProp != null)
                    && (this.columnsFilterProp.size() > 0)) {
                Enumeration e = this.columnsFilterProp.propertyNames();

                while (e.hasMoreElements()) {
                    String tableName = (String) e.nextElement();
                    this.sourceMD.getSchema().addTableColumnsFilter(tableName,
                            this.columnsFilterProp.getProperty(tableName));
                }
            }
        } catch (SQLException se) {
            throw se;
        } catch (Exception e) {
            throw new SQLException(e.getMessage());
        }
    }

    public void migrateGrants() throws Exception {
        try {
            String commaSepUserNames = null;

            if (this.userNames != null) {
                commaSepUserNames = getCommaSepObjectNames(this.userNames);
            }

            this.sourceMD.getAllGrants(commaSepUserNames);
        } catch (SQLException sqle) {
            failureCount += 1;
            if (sqle.getErrorCode() == 942) {
                throw new SQLException(ResourceHandler.getValue(
                        "ERR_INSUFFICIENT_ORA_PRIV_GRANT", rbParameters));
            }
            throw sqle;
        }
        try {
            for (int i = 0; i < this.sourceMD.getSchema().getGrants().size(); i++) {
                Grant grant = this.sourceMD.getSchema().getGrants().get(i);
                if ((grant.getObjectName() != null)
                        && (grant.getObjectName().trim()
                        .equalsIgnoreCase("database")))
                    grant.setObjectName("DATABASE "
                            + this.targetMD.getDatabaseName());
                else if ((grant.getObjectName() != null)
                        && (grant.getObjectName().trim()
                        .equalsIgnoreCase("schema")))
                    grant.setObjectName("SCHEMA "
                            + this.targetMD.getSchema().getName());
                try {
                    String sql = this.tddl.getCreateScript(grant);
                    if (sql.compareTo("") != 0) {
                        if (grant.getPrivilegeType() == Grant.PRIV_TYPE.ROLE) {
                            rbParameters = new String[]{
                                    grant.getObjectName(), grant.getGrantee()};
                            logMessage(ResourceHandler.getValue(
                                    "INFO_GRANTING_ROLE", rbParameters));
                        } else {
                            rbParameters = new String[]{
                                    grant.getPrivilege(),
                                    grant.getSchema() + "."
                                            + grant.getObjectName(),
                                    grant.getGrantee()};
                            logMessage(ResourceHandler.getValue(
                                    "INFO_GRANTING_PRIVILEGE", rbParameters));
                        }

                        if (this.offlineMigration) {
                            this.targetMD.saveScript(sql,
                                    MTKConstants.ObjectTypes.GRANT);
                        } else {
                            this.summary.alertNewGrant(grant);
                            this.targetMD.executeScript(sql);
                            this.summary.alertSuccessGrant(grant);
                        }
                    }
                } catch (Exception cex) {
                    failureCount += 1;
                    if (grant.getPrivilegeType() == Grant.PRIV_TYPE.ROLE) {
                        rbParameters = new String[]{grant.getObjectName(),
                                grant.getGrantee(), cex.getMessage()};
                        logMessage(ResourceHandler.getValue(
                                "ERR_GRANTING_ROLE", rbParameters), Level.ERROR);
                    } else {
                        rbParameters = new String[]{
                                grant.getPrivilege(),
                                grant.getSchema() + "." + grant.getObjectName(),
                                grant.getGrantee(), cex.getMessage()};
                        logMessage(ResourceHandler.getValue(
                                        "ERR_GRANTING_PRIVILEGE", rbParameters),
                                Level.ERROR);
                    }
                }
            }
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_GRANTING", rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void migrateUsers() throws Exception {
        try {
            if (this.userNames == null) {
                this.sourceMD.getAllRoles();
                this.sourceMD.getAllUsers();
            } else {
                this.sourceMD.getRoles(getCommaSepObjectNames(this.userNames));
                this.sourceMD
                        .getAllUsers(getCommaSepObjectNames(this.userNames));
            }
        } catch (SQLException sqle) {
            failureCount += 1;

            if (sqle.getErrorCode() == 942) {
                throw new SQLException(ResourceHandler.getValue(
                        "ERR_INSUFFICIENT_ORA_PRIV", rbParameters));
            }
            throw sqle;
        }

        if (this.userNames != null) {
            int usersRolesCount = this.sourceMD.getSchema().getRoles() == null ? 0
                    : this.sourceMD.getSchema().getRoles().size();
            usersRolesCount += (this.sourceMD.getSchema().getUsers() == null ? 0
                    : this.sourceMD.getSchema().getUsers().size());

            if (usersRolesCount != this.userNames.length) {
                failureCount += 1;
                throw new MTKException(ResourceHandler.getValue(
                        "ERR_SRC_DB_USERS_NOT_FOUND",
                        new String[]{this.sourceDBType.getString()}));
            }
        }

        try {
            for (int i = 0; i < this.sourceMD.getSchema().getRoles().size(); i++) {
                Role role = this.sourceMD.getSchema().getRoles().get(i);
                try {
                    String sql = this.tddl.getCreateScript(role);
                    if (sql.compareTo("") != 0) {
                        rbParameters = new String[]{role.getRoleName()};
                        logMessage(ResourceHandler.getValue(
                                "INFO_CREATING_ROLE", rbParameters));
                        if (this.offlineMigration) {
                            this.targetMD.saveScript(sql,
                                    MTKConstants.ObjectTypes.ROLE);
                        } else {
                            this.summary.alertNewRole(role);
                            this.targetMD.executeScript(sql);
                            this.summary.alertSuccessRole(role);
                        }
                    }
                } catch (Exception cex) {
                    failureCount += 1;
                    rbParameters = new String[]{role.getRoleName(),
                            cex.getMessage()};
                    logMessage(ResourceHandler.getValue("ERR_CREATING_ROLE",
                            rbParameters), Level.ERROR);
                }
            }
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_ROLE",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
        try {
            for (int i = 0; i < this.sourceMD.getSchema().getUsers().size(); i++) {
                User user = this.sourceMD.getSchema().getUsers().get(i);
                try {
                    String sql = this.tddl.getCreateScript(user);
                    if (sql.compareTo("") != 0) {
                        rbParameters = new String[]{user.getName()};
                        logMessage(ResourceHandler.getValue(
                                "INFO_CREATING_USER", rbParameters));
                        if (this.offlineMigration) {
                            this.targetMD.saveScript(sql,
                                    MTKConstants.ObjectTypes.USER);
                        } else {
                            this.summary.alertNewUser(user);
                            this.targetMD.executeScript(sql);
                            this.summary.alertSuccessUser(user);
                        }
                    }
                } catch (Exception cex) {
                    failureCount += 1;
                    rbParameters = new String[]{user.getName(),
                            cex.getMessage()};
                    logMessage(ResourceHandler.getValue("ERR_CREATING_USER",
                            rbParameters), Level.ERROR);
                }
            }
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_USER",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void importSchema(String sourceSchema, boolean copyTableDDL,
                             boolean copyTableData, boolean dropSchema, boolean importTables,
                             boolean importConstraints, boolean importIndexes,
                             boolean importSynonyms, boolean importTriggers,
                             boolean importViews, boolean importSequences, boolean importProcs,
                             boolean importFuncs, boolean importPackages, boolean importDBLinks,
                             boolean importObjectTypes, boolean importRules,
                             boolean truncateBeforeLoad, boolean safeMode,
                             boolean importDomains, boolean importPublicSynonyms,
                             boolean importPrivateSynonyms) throws Exception {
        String[] params = {sourceSchema};

        failureCount = 0;
        try {
            if ((this.targetDBType == MTKConstants.DATABASE_TYPE.NPS)
                    && ((getNZOptionValue("host") == null)
                    || (getNZOptionValue("db") == null)
                    || (getNZOptionValue("u") == null) || (getNZOptionValue("pw") == null))) {
                Map<String, String> npsConnParams = Utility.getNPSCredentials(
                        this.targetConn.getConnection(), this.targetSchema);
                Set<String> keySet = npsConnParams.keySet();

                for (String key : keySet) {
                    if (key.equalsIgnoreCase("Database"))
                        nzOptions.put("db", npsConnParams.get(key));
                    else if (key.equalsIgnoreCase("Servername"))
                        nzOptions.put("host", npsConnParams.get(key));
                    else if (key.equalsIgnoreCase("UID"))
                        nzOptions.put("u", npsConnParams.get(key));
                    else if (key.equalsIgnoreCase("PWD"))
                        nzOptions.put("pw", npsConnParams.get(key));
                }
            }
        } catch (SQLException sqle) {
            failureCount += 1;
            throw sqle;
        }

        try {
            if (this.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                logMessage(ResourceHandler.getValue(
                        "INFO_IMPORT_REDWOOD_SCHEMA", params));
            else if (this.sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                logMessage(ResourceHandler.getValue("INFO_IMPORT_EDB_SCHEMA",
                        params));
            else if (this.sourceDBType == MTKConstants.DATABASE_TYPE.MYSQL)
                logMessage(ResourceHandler.getValue("INFO_IMPORT_MYSQL_SCHEMA",
                        params));
            else if (this.sourceDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
                logMessage(ResourceHandler.getValue(
                        "INFO_IMPORT_SQLSERVER_SCHEMA", params));
            else if (this.sourceDBType == MTKConstants.DATABASE_TYPE.DB2)
                logMessage(ResourceHandler.getValue("INFO_IMPORT_DB2_SCHEMA",
                        params));
            else if (this.sourceDBType == MTKConstants.DATABASE_TYPE.SYBASE) {
                logMessage(ResourceHandler.getValue(
                        "INFO_IMPORT_SYBASE_SCHEMA", params));

            }

            createSchema(dropSchema);

            if ((!this.offlineMigration)
                    && ((this.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                    || (this.targetDBType == MTKConstants.DATABASE_TYPE.NPS) || (this.targetDBType == MTKConstants.DATABASE_TYPE.SRDB))) {
                configPGGUCs(this.targetSchema, this.targetDBType,
                        this.targetMD);

                this.targetConn.commit();
            }

            if (importObjectTypes) {
                copyObjectTypes();
            }

            if (importDomains) {
                copyDomains(this.domainNames);
                copyCustomTypes((String[]) null);
            }

            if (importSequences) {
                copySequences(this.sequenceNames);
            }
            System.out.println("start migration");
            //
            if (importTables) {
                try {
                    if (((this.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB) || (this.targetDBType == MTKConstants.DATABASE_TYPE.SRDB))
                            && (!this.offlineMigration)
                            && (((this.targetMD.getDBServerMajorVersion() == 9) && (this.targetMD
                            .getDBServerMinorVersion() == 0)) || (this.targetMD
                            .getDBServerMajorVersion() < 9))) {
                        this.useOraPartitionSyntax = false;
                    }

                    copyTables(this.tableNames, copyTableDDL, copyTableData,
                            truncateBeforeLoad, safeMode, this.copyDelimiter);
                } catch (SQLException sqle) {
                    failureCount += 1;

                    rbParameters = new String[]{sqle.getMessage()};
                    Utility.getLogger().warn(
                            ResourceHandler.getValue("ERR_IN_COPY_TABLES",
                                    rbParameters));
                    Utility.getLogger().error("Stack Trace:", sqle);
                }

            }
            migrateTableFlag = true;
            iuiOperation.infoProgress(getMigrationProcess());
//            System.out.println("MigrationToolkit4036        tableNum:" + tableNum + ";migratedTables:" + migratedTables);
            //导入约束
            if (importConstraints) {
                copyConstraints(this.tableNames);
            }
            migrateConstraintsFlag = true;
            iuiOperation.infoProgress(getMigrationProcess());
//            System.out.println("MigrationToolkit4036        constraintsNum:" + constraintsNum + ";migratedContraints:" + migratedConstraints);
            //导入索引
            if (importIndexes) {
                copyIndexes(this.tableNames);
            }
            migrateIndexFlag = true;
            iuiOperation.infoProgress(getMigrationProcess());
//            System.out.println("MigrationToolkit4036        indexNum:" + indexNum + ";migratedIndexes:" + migratedIndexes);

            System.out.println("importTriggers:" + importTriggers);
//            importTriggers = true;
            if (importTriggers) {
                copyTriggers(this.tableNames);
            }

            System.out.println("importViews:" + importViews);
            if (importViews) {
                copyViews(this.viewNames);
            }
            migrateViewFlag = true;
            iuiOperation.infoProgress(getMigrationProcess());
//            System.out.println("MigrationToolkit4061       viewNum:" + viewNum + ";migratedViews:" + migratedViews);
            System.out.println("importProcs:" + importProcs);
            if (importProcs) {
                copyProcedures(this.procNames);
            }

            System.out.println("importFuncs:" + importFuncs);
            if (importFuncs) {
                copyFunctions(this.funcNames);
            }

            System.out.println("importPackages:" + importPackages);
            if (importPackages) {
                copyPackages(this.packageNames);
            }

            System.out.println("importSynonyms:" + importSynonyms);
            if (importSynonyms) {
                copySynonyms(this.synonymNames);
            } else {
                if (importPublicSynonyms) {
                    copyPublicPrivateSynonyms(true);
                }

                if (importPrivateSynonyms) {
                    copyPublicPrivateSynonyms(false);
                }
            }

            System.out.println("importDBLinks:" + importDBLinks);
            if (importDBLinks) {
                copyDBLinks();
            }

            System.out.println("importRules:" + importRules);
            if (importRules) {
                copyRules(this.ruleNames);
            }

            logMessage("");

            if (failureCount == 0)
                logMessage(ResourceHandler.getValue(
                        "INFO_IMPORT_SCHEMA_FINISHED_OK",
                        new String[]{sourceSchema}));
            else {
                logMessage(ResourceHandler.getValue(
                        "INFO_IMPORT_SCHEMA_FINISHED_ERR",
                        new String[]{sourceSchema}));
            }
            migrateFlag = true;
            iuiOperation.infoProgress(getMigrationProcess());

            logMessage("");
        } finally {
            if (this.targetMD != null)
                this.targetMD.closeScriptWriters();
        }
    }

    public void closeConnections() {
        if ((this.srcConn != null) && (this.srcConn.getConnection() != null))
            try {
                this.srcConn.getConnection().close();
            } catch (SQLException ex) {
            }
        if ((this.targetConn != null)
                && (this.targetConn.getConnection() != null))
            try {
                this.targetConn.getConnection().close();
            } catch (SQLException ex) {
            }
    }

    public void createSchema(boolean dropSchema) throws SQLException,
            IOException, MTKException {
        boolean schemaExists = false;

        if (!this.offlineMigration) {
            schemaExists = this.targetMD.schemaExists(this.targetSchema);

            if ((this.targetDBType == MTKConstants.DATABASE_TYPE.NPS)
                    && (!schemaExists)) {
                throw new MTKException(ResourceHandler.getValue(
                        "ERR_NPS_LINKED_SCHEMA_NOT_FOUND",
                        new String[]{this.targetSchema}));
            }

        }

        String tempTargetSchemaName = this.targetSchema;
        if (this.flagUserSpecifiedTargetSchemaName)
            tempTargetSchemaName = this.targetMD
                    .isCaseSensitive(tempTargetSchemaName) ? "\""
                    + tempTargetSchemaName + "\"" : tempTargetSchemaName;
        else {
            tempTargetSchemaName = this.sourceMD
                    .isCaseSensitive(tempTargetSchemaName) ? "\""
                    + tempTargetSchemaName + "\"" : tempTargetSchemaName;
        }

        if (this.offlineMigration) {
            this.targetMD.saveScript(
                    this.tddl.getCreateSchemaScript(tempTargetSchemaName),
                    MTKConstants.ObjectTypes.SCHEMA);
        } else {
            if ((dropSchema) && (schemaExists)) {
                try {
                    rbParameters = new String[]{this.targetSchema};
                    logMessage(ResourceHandler.getValue("INFO_DROPPING_SCHEMA",
                            rbParameters));
                    this.targetMD.executeScript(this.tddl
                            .getDropSchemaScript(tempTargetSchemaName));
                } catch (Exception ex) {
                    throw new SQLException(ex.getMessage());
                }
            }

            if ((dropSchema) || (!schemaExists)) {
                rbParameters = new String[]{this.targetSchema};
                logMessage(ResourceHandler.getValue("INFO_CREATING_SCHEMA",
                        rbParameters));
                this.targetMD.executeScript(this.tddl
                        .getCreateSchemaScript(tempTargetSchemaName));
            }
        }
    }

    public boolean loadDBLinkOra() throws FileNotFoundException, IOException,
            SQLException {
        if (!((MetaData) this.targetMD).isDBLinkOraInstalled()) {
            String path = "dblink_ora_inst.sql";
            InputStream inStream = MigrationToolkit.class.getClassLoader()
                    .getResourceAsStream(path);

            if (inStream == null) {
                logMessage(ResourceHandler.getValue("ERR_LOAD_DBLINKORA_FILE",
                        new String[]{path}));
                return false;
            }

            BufferedReader bufferReader = new BufferedReader(
                    new InputStreamReader(inStream));
            StringBuilder ora_sql = new StringBuilder();
            String temp;
            while ((temp = bufferReader.readLine()) != null) {
                ora_sql.append(temp);
                ora_sql.append("\n");
            }

            bufferReader.close();
            this.targetMD.executeScript(ora_sql.toString());
        }
        return true;
    }

    public void removeDBLinkOra() throws FileNotFoundException, IOException,
            SQLException {
        String path = "dblink_ora_uninst.sql";
        InputStream inStream = MigrationToolkit.class.getClassLoader()
                .getResourceAsStream(path);

        if (inStream == null) {
            logMessage(ResourceHandler.getValue("ERR_LOAD_DBLINKORA_FILE",
                    new String[]{path}));
            return;
        }

        BufferedReader bufferReader = new BufferedReader(new InputStreamReader(
                inStream));
        String sql;
        while ((sql = bufferReader.readLine()) != null)
            try {
                this.targetMD.executeScript(sql);
            } catch (SQLException ex) {
            }
        bufferReader.close();
    }

    public void copyTables(String[] sourceTableNames, boolean copyTableDDL,
                           boolean copyTableData, boolean truncateBeforeLoad,
                           boolean safeMode, char copyDelimeter) throws SQLException,
            MTKException {
        String commaSepTableNames = getCommaSepObjectNames(sourceTableNames);

        if (commaSepTableNames != null) {
            rbParameters = new String[]{commaSepTableNames.toString()};
            logMessage(ResourceHandler
                    .getValue("INFO_TABLE_LIST", rbParameters));
            this.sourceMD.getTables(commaSepTableNames,
                    this.flagImportViewAsTable);
        } else {
            this.sourceMD.getAllTables();
        }

        /***
         * 统计共有多少张表供迁移
         */
        tableNum = sourceMD.getSchema().getTables().size();
//        System.out.println("MigrationToolkit4240" + tableNum);

        if ((commaSepTableNames == null)
                && (this.sourceMD.getSchema().getTables() == null)) {
            logMessage(ResourceHandler.getValue("INFO_NO_TABLE_TO_MIGRATE",
                    null));
            return;
        }

        if ((sourceTableNames != null)
                && ((this.sourceMD.getSchema().getTables() == null) || (sourceTableNames.length != this.sourceMD
                .getSchema().getTables().size()))) {
            if (this.flagGenStats) {
                this.propRepStats.setProperty("STATUS", "F");
            }

            failureCount += 1;

            if (this.flagExitOnError) {
                throw new MTKException(ResourceHandler.getValue(
                        "ERR_SRC_DB_TABLES_MISSING",
                        new String[]{this.sourceDBType.getString()}));
            }
            throw new MTKException(ResourceHandler.getValue(
                    "ERR_SRC_DB_TABLES_NOT_FOUND",
                    new String[]{this.sourceDBType.getString()}));
        }

        copyTables(this.sourceMD.getSchema().getTables(), copyTableDDL,
                copyTableData, truncateBeforeLoad, safeMode, copyDelimeter);
    }

    public void copyTables(TableList list, boolean copyTableDDL,
                           boolean copyTableData, boolean truncateBeforeLoad,
                           boolean safeMode, char copyDelimeter) throws SQLException,
            MTKException {
        if ((list == null) || (list.size() == 0)) {
            return;
        }

        if (dataLoadThreadCount > list.size()) {
            dataLoadThreadCount = list.size();
        }

        long totalRows = 0L;
        double totalTime = 0.0D;
        DataLoader loader = null;
        Date startTime = new Date();
        try {
            MTKData sourceData = this.mtkFactory.createMTKData(
                    this.sourceDBType, this.srcConn, cpBatchSize);

            if ((copyTableDDL) && ((!this.flagFastCopy) || (safeMode))) {
                logMessage(ResourceHandler.getValue("INFO_CREATING_TABLES",
                        null));

                int tableCount = 0;

                for (int tableIndex = 0; tableIndex < list.size(); tableIndex++) {
                    try {
                        Table table = list.get(tableIndex);
                        rbParameters = new String[]{table.getName()};
                        logMessage(ResourceHandler.getValue(
                                "INFO_CREATING_TABLE", rbParameters));

                        for (int i = 0; i < table.getEnumTypesCount(); i++) {
                            EnumType et = table.getEnumType(i);
                            if (et != null) {
                                if (this.offlineMigration)
                                    this.targetMD.saveScript(et.getSQL(),
                                            MTKConstants.ObjectTypes.TABLE);
                                else {
                                    try {
                                        this.targetMD
                                                .executeScript(et.getSQL());
                                    } catch (Exception exp) {
                                    }
                                }
                            }
                        }

                        if (this.offlineMigration) {
                            this.targetMD.saveScript(
                                    this.tddl.getCreateScript(table),
                                    MTKConstants.ObjectTypes.TABLE);
                        } else {
                            this.summary.alertNewTable(table);
                            this.targetMD.executeScript(this.tddl
                                    .getCreateScript(table));
                            this.summary.alertSuccessTable(table);
                        }

                        tableCount++;
                    } catch (Exception e) {
                        rbParameters = new String[]{
                                list.get(tableIndex).getName(), e.getMessage()};
                        Utility.getLogger().warn(
                                ResourceHandler.getValue(
                                        "ERR_REATING_TABLE_WITH_MSG",
                                        rbParameters));
                        Utility.getLogger().error("Stack Trace:", e);
                        list.get(tableIndex).setCreationFailure(true);
                        failureCount += 1;

                        if (!this.flagExitOnError)
                            continue;
                        if (this.flagGenStats) {
                            this.propRepStats.setProperty("STATUS", "F");
                        }

                        throw new MTKException(ResourceHandler.getValue(
                                "ERR_TABLE_CREATION_FAIL_REASON",
                                new Object[]{
                                        this.sourceMD.getSchema().getTables()
                                                .get(tableIndex).getName(),
                                        this.targetDBType.getString(),
                                        e.getMessage()}));
                    }
                    /**
                     * 完成创建表
                     */
//                    System.out.println("migrationtoolkit4353********************");
                }

                if (this.flagGenStats) {
                    this.propRepStats.setProperty("STATUS", "S");
                }
                rbParameters = new String[]{String.valueOf(tableCount)};
                logMessage(ResourceHandler.getValue(
                        "INFO_CREATED_TABLES_COUNT", rbParameters));
            }

            if (this.isDBLinkOra) {
                try {
                    if (!((MetaData) this.targetMD).isDBLinkOraInstalled())
                        throw new MTKException(
                                "Could not load DBLinkOra Module");
                } catch (Exception ex) {
                    try {
                        if (((this.targetMD.getDBServerMajorVersion() == 8) && (this.targetMD
                                .getDBServerMinorVersion() >= 4))
                                || (this.targetMD.getDBServerMajorVersion() > 8)) {
                            logMessage(ResourceHandler.getValue(
                                    "ERR_LOAD_DBLINKORA_84",
                                    new String[]{ex.getMessage()}));
                        } else
                            logMessage(ResourceHandler.getValue(
                                    "ERR_LOAD_DBLINKORA",
                                    new String[]{ex.getMessage()}));
                    } catch (Exception exp) {
                    }
                    throw new MTKException(ex);
                }

            }

//            System.out.println("MigrationToolkit4398*********copyTableData" + copyTableData);
            if (copyTableData) {
                loader = new DataLoader(
                        dataLoadThreadCount,
                        this,
                        this.summary,
                        this.sourceDBType,
                        this.offlineMigration ? MTKConstants.DATABASE_TYPE.OFFLINE
                                : this.targetDBType, truncateBeforeLoad,
                        copyDelimeter, this.escapeTabDelimiter, copyTableDDL,
                        this.flagFastCopy, this.offlineMigration,
                        this.flagExitOnError, this.isDBLinkOra,
                        this.targetSchema);

                if ((this.filterProp != null) && (this.filterProp.size() > 0)) {
                    for (int i = 0; i < list.size(); i++) {
                        String tableName = list.get(i).getName();
                        boolean tableFilterFound = this.filterProp
                                .containsKey(tableName);
                        if ((tableFilterFound)
                                && (this.filterProp.getProperty(tableName) != null)) {
                            list.get(i).setWhereClause(
                                    this.filterProp.getProperty(tableName));
                        }

                    }

                }

                if ((!this.flagGenStats)
                        && (this.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)) {
                    for (int i = 0; i < list.size(); i++) {
                        Table table = list.get(i);

                        this.targetMD.dropTableConsts(this.sourceDBType, table,
                                MTKConstants.TABLE_CONSTRAINT_TYPE.FOREIGN_KEY);
                    }

                }

                if (safeMode) {
                    logMessage(ResourceHandler.getValue(
                            "INFO_LOADING_TABLE_DATA_SAFE_MODE", null));

                    for (int i = 0; i < list.size(); i++) {
                        Table table = list.get(i);
                        loader.queDataForSafeMode(table);
                    }
                    loader.startLoading();
                    rbParameters = new String[]{
                            String.valueOf(loader.getTotalTime() / 1000.0D),
                            String.valueOf(loader.getTotalRows()),
                            String.valueOf(loader.getTotalDataSize() / 1000.0D)};
                    logMessage(ResourceHandler.getValue(
                            "INFO_DATA_LOAD_SUMMARY", rbParameters));
                } else {
                    if (!this.isDBLinkOra) {
                        if (this.targetDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                            rbParameters = new String[]{String
                                    .valueOf(batchSize) + " rows"};
                        else {
                            rbParameters = new String[]{String
                                    .valueOf(cpBatchSize == 0 ? 16
                                            : cpBatchSize)
                                    + " MB"};
                        }

                        logMessage(ResourceHandler.getValue(
                                "INFO_LOADING_TABLE_DATA_SIZE", rbParameters));
                    }

                    for (int i = 0; i < list.size(); i++) {
                        Table table = list.get(i);
                        loader.queDataForFastMode(table);
                    }
                    loader.startLoading();// 首次迁移
                    if (this.targetDBType != MTKConstants.DATABASE_TYPE.NPS) {
                        for (int i = 0; i < list.size(); i++) {
                            Table table = list.get(i);
                            if ((table.isCreationFailure())
                                    || (!table.hasDataLoadFailure())
                                    || (table.hasLargeObject())) {
                                continue;
                            }

                            loader.queDataForFailedFastMode(table);
                        }

                    }

                    for (int i = 0; i < list.size(); i++) {
                        Table table = list.get(i);
                        loader.queDataForLoMode(table);
                    }

                    loader.startLoading();// 二次迁移

                    if (truncateBeforeLoad) {
                        restoreAllTablesConstsAndIndexes(list);

                        if ((!this.flagGenStats)
                                && (this.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)) {
                            this.flagSkipPKConst = true;
                            this.flagSkipCKConst = true;

                            for (int tableIndex = 0; tableIndex < list.size(); tableIndex++) {
                                Table table = list.get(tableIndex);
                                this.sourceMD.clearConstraintsList();
                                copyConstraints(
                                        new String[]{Utility.removeEnclosingQuotes(table
                                                .getName())}, this.sourceMD,
                                        this.targetMD);
                            }

                        }

                    }

                    if (this.flagVacuumAnalyze) {
                        if (this.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) {
                            logMessage(ResourceHandler.getValue(
                                    "INFO_PERFORM_VACUM_ANALYZE_ON_PG", null));
                        } else {
                            logMessage(ResourceHandler.getValue(
                                    "INFO_PERFORM_VACUM_ANALYZE_ON_EDB", null));
                        }

                        for (int tableIndex = 0; tableIndex < list.size(); tableIndex++) {
                            Table table = list.get(tableIndex);
                            this.targetMD.executeScript("VACUUM ANALYZE "
                                    + table.getTargetSchemaFullyQualifiedName(
                                    this.sourceDBType,
                                    this.targetDBType, true));
                        }
                    } else if (this.flagAnalyze) {
                        if (this.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) {
                            logMessage(ResourceHandler.getValue(
                                    "INFO_PERFORMING_ANALYZE_ON_PG", null));
                        } else {
                            logMessage(ResourceHandler.getValue(
                                    "INFO_PERFORMING_ANALYZE_ON_EDB", null));
                        }

                        for (int tableIndex = 0; tableIndex < list.size(); tableIndex++) {
                            Table table = list.get(tableIndex);
                            this.targetMD.executeScript("ANALYZE "
                                    + table.getTargetSchemaFullyQualifiedName(
                                    this.sourceDBType,
                                    this.targetDBType, true));
                        }
                    }

                    if (this.flagGenStats) {
                        if (failureCount == 0) {
                            this.propRepStats.setProperty("STATUS", "S");
                        } else {
                            this.propRepStats.setProperty("STATUS", "W");
                            this.propRepStats
                                    .setProperty("ERROR_MESSAGE",
                                            "One or more tables could not be replicated. Read output log for more details.");
                        }

                    }

                    totalTime = new Date().getTime() - startTime.getTime();
                    rbParameters = new String[]{
                            String.valueOf(totalTime / 1000.0D),
                            String.valueOf(loader.getTotalRows()),
                            String.valueOf(loader.getTotalDataSize() / 1000.0D)};
                    logMessage(ResourceHandler.getValue(
                            "INFO_DATA_LOAD_SUMMARY", rbParameters));
                }

                totalRows = loader.getTotalRows();
            }

            sourceData.setLastTable("");
        } finally {
            if (this.flagGenStats) {
                if (copyTableData) {
                    this.propRepStats.setProperty("ROW_COUNT",
                            String.valueOf(totalRows));
                    this.propRepStats.setProperty("END_TIME",
                            Utility.formatDate(new Date(), null));
                    this.propRepStats.setProperty("DURATION",
                            String.valueOf(new Double(totalTime / 1000.0D)));
                } else if (copyTableDDL) {
                    if (failureCount == 0) {
                        this.propRepStats.setProperty("STATUS", "S");
                    } else {
                        this.propRepStats.setProperty("STATUS", "F");

                        if (lastErrorMessage != null) {
                            this.propRepStats.setProperty("ERROR_MESSAGE",
                                    lastErrorMessage);
                        }
                    }
                }
            }
            this.targetMD.executeScript("update sr_class set relpersistence='p' where relpersistence='u';");
        }

        if (loader != null)
            loader.finalize();
    }

    private void restoreAllTablesConstsAndIndexes(TableList list)
            throws SQLException {
        for (int tableIndex = 0; tableIndex < list.size(); tableIndex++) {
            Table table = list.get(tableIndex);

            if (((!table.isPartitioned()) && (!this.enableConstBeforeDataLoad))
                    || (isMemberOfPartitionTableList(table))) {
                enableTableContraints(table.getTargetSchemaFullyQualifiedName(
                                this.sourceDBType, this.targetDBType, true),
                        this.targetMD);
            }

            if (this.flagGenStats)
                restoreTableConstsAndIndexes(table, this.sourceMD,
                        this.targetMD);
            else
                enableTableIndexes(table.getTargetSchemaFullyQualifiedName(
                                this.sourceDBType, this.targetDBType, true),
                        this.targetMD);
        }
    }

    protected void displayTableDataLoadSummary(double totalTime,
                                               long totalRows, double totalDataSizeKBytes) {
        displayTableDataLoadSummary(null, totalTime, totalRows,
                totalDataSizeKBytes);
    }

    protected void displayTableDataLoadSummary(String tableName,
                                               double totalTime, long totalRows, double totalDataSizeKBytes) {
        double totalTimeSecs = totalTime / 1000.0D;
        double totalMBytes = totalDataSizeKBytes / 1024.0D;
        rbParameters = new String[]{String.valueOf(totalTimeSecs),
                String.valueOf(totalRows)};
        String infoSummary = ResourceHandler.getValue("INFO_SUMMARY_PART1",
                rbParameters);

        if (totalMBytes > 0.0D) {
            rbParameters = new String[]{String.valueOf(totalMBytes)};
            infoSummary = infoSummary
                    + " "
                    + ResourceHandler.getValue("INFO_SUMMARY_PART2",
                    rbParameters);
        }

        if (tableName != null) {
            infoSummary = "[" + tableName + "] " + infoSummary;
        }
        logMessage(infoSummary);
    }

    public void copyConstraints(ConstraintList list) throws SQLException {
        copyConstraints(list, this.targetMD);
    }

    public void copyConstraints(ConstraintList list, MTKMetaData targetMD)
            throws SQLException {
        if ((list == null) || (list.size() == 0)) {
            return;
        }
        for (int i = 0; i < list.size(); i++) {
            Constraint constraint = list.get(i);
            try {
                if ((constraint.getType() == 'P')
                        || (constraint.getType() == 'U')
                        || (constraint.getType() == 'F')
                        || (constraint.getType() == 'K')) {
                    if (this.flagSkipPKConst) {
                        continue;
                    }
                    String sql = this.tddl.getCreateScript(constraint);
//                    System.out.println(sql);
                    if (sql.compareTo("") != 0) {
                        rbParameters = new String[]{constraint.getName()};

                        if ((!this.flagGenStats) || (!this.dataOnlyMode)) {
                            logMessage(ResourceHandler.getValue(
                                    "INFO_CREATING_CONSTRAINT", rbParameters));
                        }

                        if (this.offlineMigration) {
                            targetMD.saveScript(sql,
                                    MTKConstants.ObjectTypes.CONSTRAINT);
                        } else {
                            this.summary.alertNewConstraint(constraint);
                            targetMD.executeScript(sql);
                            this.summary.alertSuccessConstraint(constraint);
                        }
                    }
//                    System.out.println("################migrationtoolkit4714");
                    addMigratedConstraints();
                }
            } catch (Exception cex) {
                if (((cex instanceof SQLException))
                        && (this.targetDBType == MTKConstants.DATABASE_TYPE.ORACLE)) {
                    if (((SQLException) cex).getErrorCode() == 2329) {
                        logMessage(ResourceHandler.getValue(
                                "ERR_CREATING_CONSTRAINT_WITH_ERR_MSG",
                                new String[]{constraint.getName(),
                                        cex.getMessage()}));
                        this.summary.alertFail("CONSTRAINT", constraint);
                    }
                } else {
                    failureCount += 1;
                    rbParameters = new String[]{constraint.getName(),
                            cex.getMessage()};
                    logMessage(ResourceHandler.getValue(
                                    "ERR_CREATING_CONSTRAINT", rbParameters),
                            Level.ERROR);
                }
            }
        }

        for (int i = 0; i < list.size(); i++) {
            Constraint constraint = list.get(i);
            try {
                if ((constraint.getType() != 'P')
                        && (constraint.getType() != 'p')
                        && (constraint.getType() != 'U')
                        && (constraint.getType() != 'u')) {
                    if ((this.flagSkipFKConst)
                            && ((constraint.getType() != 'R')
                            && (constraint.getType() != 'r') && (constraint
                            .getType() == 'f'))) {
                        continue;
                    }

                    if ((this.flagSkipCKConst)
                            && ((constraint.getType() != 'C') && (constraint
                            .getType() == 'c'))) {
                        continue;
                    }

                    if ((!flagIgnoreCheckConstFilter)
                            && ((constraint.getType() == 'C') || (constraint
                            .getType() == 'c'))
                            && (this.sourceDBType != MTKConstants.DATABASE_TYPE.ORACLE)
                            && (this.sourceDBType != MTKConstants.DATABASE_TYPE.ENTERPRISEDB)
                            && (this.sourceDBType != MTKConstants.DATABASE_TYPE.SRDB)
                            && (this.sourceDBType != MTKConstants.DATABASE_TYPE.SQLSERVER)) {
                        continue;
                    }

                    String sql = this.tddl.getCreateScript(constraint);
                    if (sql.compareTo("") != 0) {
                        rbParameters = new String[]{constraint.getName()};

                        if ((!this.flagGenStats) || (!this.dataOnlyMode)) {
                            logMessage(ResourceHandler.getValue(
                                    "INFO_CREATING_CONSTRAINT", rbParameters));
                        }

                        if (this.offlineMigration) {
                            targetMD.saveScript(sql,
                                    MTKConstants.ObjectTypes.CONSTRAINT);
                        } else {
                            this.summary.alertNewConstraint(constraint);
                            targetMD.executeScript(sql);
                            this.summary.alertSuccessConstraint(constraint);
                        }
//                        System.out.println("%%%%%%%%%%%%%%%%migrationtoolkit4784");
                        addMigratedConstraints();
                    }
                }
            } catch (Exception cex) {
                if ((this.flagGenStats)
                        && ((cex instanceof SQLException))
                        && ((constraint.getType() == 'R')
                        || (constraint.getType() == 'r') || (constraint
                        .getType() == 'f'))
                        && (((SQLException) cex).getSQLState()
                        .equalsIgnoreCase("42P01"))) {
                    this.summary.alertSuccessConstraint(constraint);
                } else {
                    failureCount += 1;
                    rbParameters = new String[]{constraint.getName(),
                            cex.getMessage()};
                    logMessage(ResourceHandler.getValue(
                            "ERR_CREATING_CONSTRAINT_WITH_ERR_MSG",
                            rbParameters), Level.ERROR);
                }
            }
        }
    }

    public void copyConstraints(String[] tableNames) throws SQLException {
        copyConstraints(tableNames, this.sourceMD, this.targetMD);
    }

    public void copyConstraints(String[] tableNames, MTKMetaData sourceMD,
                                MTKMetaData targetMD) throws SQLException {
        String commaSeptableNames = getCommaSepObjectNames(tableNames);

        if (commaSeptableNames != null) {
            sourceMD.getConstraints(commaSeptableNames);
        } else {
            sourceMD.getAllConstraints();
        }
//        System.out.println("MigrationToolkit4799   " + this.sourceMD.getSchema().getConstraints().size());
        constraintsNum = this.sourceMD.getSchema().getConstraints().size();
        try {
            copyConstraints(sourceMD.getSchema().getConstraints(), targetMD);
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_CONSTRAINT",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copyIndexes(IndexList list) throws SQLException {
        copyIndexes(list, this.targetMD);
    }

    public void copyIndexes(IndexList list, MTKMetaData targetMD)
            throws SQLException {
        if ((list == null) || (list.size() == 0)) {
            return;
        }
        for (int i = 0; i < list.size(); i++) {
            Index index = list.get(i);
            try {
                String sql = this.tddl.getCreateScript(index);
                if (sql.compareTo("") != 0) {
                    rbParameters = new String[]{index.getName()};
                    logMessage(ResourceHandler.getValue("INFO_CREATING_INDEX",
                            rbParameters));

                    if (this.offlineMigration) {
                        targetMD.saveScript(sql, MTKConstants.ObjectTypes.INDEX);
                    } else {
                        this.summary.alertNewIndex(index);
                        targetMD.executeScript(sql);
                        this.summary.alertSuccessIndex(index);
                    }
                    addMigratedIndex();
//                    System.out.println("MigrationToolkit4833" + migratedIndexes);
                }
            } catch (Exception iex) {
                if (((iex instanceof SQLException))
                        && (this.targetDBType == MTKConstants.DATABASE_TYPE.ORACLE)) {
                    if (((SQLException) iex).getErrorCode() == 1408)
                        Utility.getLogger().warn(
                                ResourceHandler.getValue("WARN_CREATING_INDEX",
                                        null));
                } else {
                    failureCount += 1;
                    rbParameters = new String[]{index.getName(),
                            iex.getMessage()};
                    logMessage(ResourceHandler.getValue(
                                    "ERR_CREATING_INDEX_WITH_ERR_MSG", rbParameters),
                            Level.ERROR);
                }
            }
        }
    }

    public void copyIndexes(String[] tableNames) throws SQLException {
        copyIndexes(tableNames, this.sourceMD, this.targetMD);
    }

    public void copyIndexes(String[] tableNames, MTKMetaData sourceMD,
                            MTKMetaData targetMD) throws SQLException {
        String commaSeptableNames = getCommaSepObjectNames(tableNames);

        if (commaSeptableNames != null) {
            sourceMD.getIndexes(commaSeptableNames);
        } else {
            sourceMD.getAllIndexes();
            indexNum = this.sourceMD.getSchema().getIndexes().size();
//            System.out.println("MigrationToolkit4864******" + indexNum);
        }
        try {
            copyIndexes(sourceMD.getSchema().getIndexes(), targetMD);
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_INDEX",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copyViews(ViewList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            View view = list.get(i);
            try {
                rbParameters = new String[]{view.getName()};
                logMessage(ResourceHandler.getValue("INFO_CREATING_VIEW",
                        rbParameters));

                if (this.offlineMigration) {
                    this.targetMD.saveScript(this.tddl.getCreateScript(view),
                            MTKConstants.ObjectTypes.VIEW);
                } else {
                    this.summary.alertNewView(view);
                    this.targetMD
                            .executeScript(this.tddl.getCreateScript(view));
                    this.summary.alertSuccessView(view);
                }
                addMigratedViews();
            } catch (Exception vex) {
                failureCount += 1;
                rbParameters = new String[]{view.getName(), vex.getMessage()};
                logMessage(ResourceHandler.getValue(
                                "ERR_CREATING_VIEW_WITH_ERR_MSG", rbParameters),
                        Level.ERROR);
            }
        }
    }

    public void copyViews(String[] viewNames) throws SQLException {
        String commaSepViewNames = getCommaSepObjectNames(viewNames);

        if (commaSepViewNames != null) {
            this.sourceMD.getViews(commaSepViewNames);
        } else {
            this.sourceMD.getAllViews();
        }
        viewNum = this.sourceMD.getSchema().getViews().size();
        try {
            copyViews(this.sourceMD.getSchema().getViews());
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_VIEWS",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copySynonyms(SynonymList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            Synonym syn = list.get(i);
            try {
                if ((this.isfirstSchemaMigrated)
                        && (this.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                        && (syn.getTable_owner() == null)) {
                    continue;
                }
                rbParameters = new String[]{syn.getSynname()};
                logMessage(ResourceHandler
                        .getValue(
                                syn.isPublic() ? "INFO_CREATING_PUBLIC_SYNONYM"
                                        : "INFO_CREATING_PRIVATE_SYNONYM",
                                rbParameters));

                if (this.offlineMigration) {
                    this.targetMD.saveScript(this.tddl.getCreateScript(syn),
                            MTKConstants.ObjectTypes.SYNONYM);
                } else {
                    this.summary.alertNewSynonym(syn);
                    this.targetMD.executeScript(this.tddl.getCreateScript(syn));
                    this.summary.alertSuccessSynonym(syn);
                }
            } catch (Exception tex) {
                failureCount += 1;
                rbParameters = new String[]{syn.getSynname(),
                        tex.getMessage()};
                logMessage(
                        ResourceHandler.getValue(
                                syn.isPublic() ? "ERR_CREATING_PUBLIC_SYNONYMS_WITH_MSG"
                                        : "ERR_CREATING_PRIVATE_SYNONYMS_WITH_MSG",
                                rbParameters), Level.ERROR);
            }
        }
    }

    public void copySynonyms(String[] synNames) throws SQLException {
        boolean isSupportSynonyms = false;

        if (!this.offlineMigration)
            isSupportSynonyms = this.targetMD.supportsSynonyms();
        else {
            isSupportSynonyms = true;
        }

        if (isSupportSynonyms) {
            String commaSeperatedSynNames = getCommaSepObjectNames(synNames);
            if (synNames != null)
                this.sourceMD.getPublicSynonyms(commaSeperatedSynNames);
            else
                this.sourceMD.getAllSynonyms();
            try {
                copySynonyms(this.sourceMD.getSchema().getSynonyms());
            } catch (Exception ex) {
                rbParameters = new String[]{ex.getMessage()};
                logMessage(ResourceHandler.getValue(
                        "ERR_CREATING_PUBLIC_SYNONYMS", rbParameters));
                throw new SQLException(ex.getMessage());
            }
        } else {
            logMessage(ResourceHandler.getValue(
                    "INFO_BACKEND_DOES_NOT_SUPPORT", null));
        }
    }

    public void copyPublicPrivateSynonyms(boolean isPublic) throws SQLException {
        boolean isSupportSynonyms = false;

        if (!this.offlineMigration)
            isSupportSynonyms = this.targetMD.supportsSynonyms();
        else {
            isSupportSynonyms = true;
        }

        if (isSupportSynonyms) {
            this.sourceMD.getSchema().getSynonyms().clear();
            if (isPublic)
                this.sourceMD.getPublicSynonym();
            else {
                this.sourceMD.getPrivateSynonyms();
            }
            try {
                copySynonyms(this.sourceMD.getSchema().getSynonyms());
            } catch (Exception ex) {
                rbParameters = new String[]{ex.getMessage()};
                logMessage(ResourceHandler
                        .getValue(isPublic ? "ERR_CREATING_PUBLIC_SYNONYMS"
                                : "ERR_CREATING_PRIVATE_SYNONYMS", rbParameters));
                throw new SQLException(ex.getMessage());
            }
        } else {
            logMessage(ResourceHandler.getValue(
                    "INFO_BACKEND_DOES_NOT_SUPPORT", null));
        }
    }

    public void copyTriggers(TriggerList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            Trigger trigger = list.get(i);
            try {
                if ((this.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                        && (!trigger.getTableOwnerName().equals(
                        trigger.getOwnerName()))) {
                    rbParameters = new String[]{trigger.getName(),
                            trigger.getOwnerName()};
                    logMessage(ResourceHandler.getValue(
                            "WRN_TRIGGER_NOT_MIGRATED", rbParameters));
                } else if (trigger.isWhenClause()) {
                    rbParameters = new String[]{trigger.getName()};
                    logMessage(ResourceHandler
                            .getValue("WRN_TRIGGER_NOT_MIGRATED_WHENCLAUSE",
                                    rbParameters));
                } else {
                    rbParameters = new String[]{trigger.getName()};
                    logMessage(ResourceHandler.getValue(
                            "INFO_CREATING_TRIGGERS", rbParameters));
                    String script = this.tddl.getCreateScript(trigger);
                    if (!this.offlineMigration) {
                        if (this.targetMD.getVersion().toLowerCase()
                                .contains("enterprisedb 8.1"))
                            script = script + ";\n/";
                        else {
                            script = script + ";";
                        }
                    } else if (!script.trim().endsWith(";")) {
                        script = script + ";";
                    }

                    if (this.offlineMigration) {
                        this.targetMD.saveScript(script,
                                MTKConstants.ObjectTypes.TRIGGER);
                    } else {
                        this.summary.alertNewTrigger(trigger);
                        this.targetMD.executeScript(script);
                        this.summary.alertSuccessTrigger(trigger);
                    }
                }
            } catch (Exception tex) {
                failureCount += 1;
                rbParameters = new String[]{trigger.getName(),
                        tex.getMessage()};
                logMessage(ResourceHandler.getValue(
                                "ERR_CREATING_TRIGGERS_WITH_MSG", rbParameters),
                        Level.ERROR);
            }
        }
    }

    public void copyTriggers(String[] triggerNames) throws SQLException {
        String commaSepTriggerNames = getCommaSepObjectNames(triggerNames);

        if (commaSepTriggerNames != null) {
            this.sourceMD.getTriggers(commaSepTriggerNames);
        } else
            this.sourceMD.getAllTriggers();
        System.out.println("MigrationToolkit 5097     " + this.sourceMD.getSchema().getTriggers().size());
        try {
            copyTriggers(this.sourceMD.getSchema().getTriggers());
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_TRIGGERS",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copySequences(SequenceList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            Sequence sequence = list.get(i);
            try {
                rbParameters = new String[]{sequence.getName()};
                logMessage(ResourceHandler.getValue("INFO_CREATING_SEQUENCES",
                        rbParameters));
                if (this.offlineMigration) {
                    this.targetMD.saveScript(
                            this.tddl.getCreateScript(sequence),
                            MTKConstants.ObjectTypes.SEQUENCE);
                } else {
                    this.summary.alertNewSequence(sequence);
                    this.targetMD.executeScript(this.tddl
                            .getCreateScript(sequence));
                    this.summary.alertSuccessSequence(sequence);
                }
            } catch (Exception sex) {
                failureCount += 1;
                rbParameters = new String[]{sequence.getName(),
                        sex.getMessage()};
                logMessage(ResourceHandler.getValue(
                                "ERR_CREATING_SEQUENCE_WITH_MSG", rbParameters),
                        Level.ERROR);
            }
        }
    }

    public void copySequences(String[] sequenceNames) throws SQLException {
        String commaSepSequenceNames = getCommaSepObjectNames(sequenceNames);

        if (commaSepSequenceNames != null) {
            this.sourceMD.getSequences(commaSepSequenceNames);
        } else {
            this.sourceMD.getAllSequences();
        }
        try {
            copySequences(this.sourceMD.getSchema().getSequences());
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_SEQUENCE",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copyPackages(PackageList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            Package pack = list.get(i);
            rbParameters = new String[]{pack.getName()};
            logMessage(ResourceHandler.getValue("INFO_CREATING_PACKAGE",
                    rbParameters));
            try {
                if (pack.getName().compareTo("QARCH_VALIDATION") == 0) {
                    rbParameters = new String[]{pack.getName()};
                    logMessage(ResourceHandler.getValue(
                            "INFO_CREATING_PACKAGE", rbParameters));
                }

                if (this.offlineMigration) {
                    this.targetMD.saveScript(
                            this.tddl.getCreateScriptPackageSpec(pack),
                            MTKConstants.ObjectTypes.PACKAGE);
                } else {
                    this.summary.alertNewPackage(pack);
                    this.targetMD.executeScript(this.tddl
                            .getCreateScriptPackageSpec(pack));
                    this.summary.alertSuccessPackage(pack);
                }
            } catch (Exception kex) {
                rbParameters = new String[]{pack.getName(), kex.getMessage()};
                logMessage(ResourceHandler.getValue(
                        "ERR_CREATING_PACKAGE_SPEC_WITH_MSG", rbParameters));
                Utility.getLogger().error("Stack Trace:", kex);
            }
            try {
                String pkgBody = this.tddl.getCreateScriptPackageBody(pack);
                if ((pkgBody == null) || (pkgBody.equals(""))) {
                    Utility.getLogger().warn(
                            ResourceHandler.getValue(
                                    "WRN_PACKAGE_BODY_IS_SKIPPING", null));
                } else if (this.offlineMigration) {
                    this.targetMD.saveScript(pkgBody,
                            MTKConstants.ObjectTypes.PACKAGE);
                } else {
                    this.summary.alertFailPackage(pack);
                    this.targetMD.executeScript(pkgBody);
                    this.summary.alertSuccessPackage(pack);
                }
            } catch (Exception kex) {
                failureCount += 1;
                rbParameters = new String[]{pack.getName(), kex.getMessage()};
                logMessage(ResourceHandler.getValue(
                                "ERR_CREATING_PACKAGE_BODY_WITH_MSG", rbParameters),
                        Level.ERROR);
                Utility.getLogger().error("Stack Trace:", kex);
            }
        }
    }

    public void copyPackages(String[] packageNames) throws SQLException {
        String commaSepPackageNames = getCommaSepObjectNames(packageNames);

        if (commaSepPackageNames != null) {
            this.sourceMD.getPackages(commaSepPackageNames);
        } else {
            this.sourceMD.getAllPackages();
        }
        try {
            copyPackages(this.sourceMD.getSchema().getPackages());
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_PACKAGE",
                    rbParameters));
            Utility.getLogger().error("Stack Trace:", ex);
            throw new SQLException(ex.getMessage());
        }
    }

    /**
     * 存储过程迁移
     *
     * @param list
     * @throws SQLException
     */
    public void copyProcedures(ProcedureList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            Procedure proc = list.get(i);
//            try {
//                rbParameters = new String[]{proc.getName()};
//                logMessage(ResourceHandler.getValue("INFO_CREATING_PROCEDURE",
//                        rbParameters));
//                if (this.offlineMigration) {
//                    this.targetMD.saveScript(this.tddl.getCreateScript(proc),
//                            MTKConstants.ObjectTypes.PROCEDURE);
//                } else {
//                    this.summary.alertNewProcedure(proc);
//                    this.targetMD
//                            .executeScript(this.tddl.getCreateScript(proc));
//                    this.summary.alertSuccessProcedure(proc);
//                }
//            } catch (Exception pex) {
//                failureCount += 1;
//                rbParameters = new String[]{proc.getName(), pex.getMessage()};
//                logMessage(ResourceHandler.getValue(
//                                "ERR_CREATING_PROCEDURE_WITH_MSG", rbParameters),
//                        Level.ERROR);
//                //mod by kevin 2015年04月28日16:02:54
//                logMessage("Procedure 原始 sql 如下：");
//                logMessage(proc.getSQL());
//                logMessage("Procedure 转换后 sql 如下：");
//                logMessage(this.tddl.getCreateScript(proc));
//            }

            Utility.appendFile("procedure_sql.sql", proc.getSQL() + " \n");
        }
    }

    public void copyProcedures(String[] procedureNames) throws SQLException {
        String commaSepProcedureNames = getCommaSepObjectNames(procedureNames);

        if (commaSepProcedureNames != null) {
            this.sourceMD.getProcedures(commaSepProcedureNames);
        } else {
            this.sourceMD.getAllProcedures();
        }
        try {
            copyProcedures(this.sourceMD.getSchema().getProcedures());
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_PROCEDURE",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    /**
     * function迁移
     *
     * @param list
     * @throws SQLException
     */
    public void copyFunctions(FunctionList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            Function func = list.get(i);
//            try {
//                rbParameters = new String[]{func.getName()};
//                logMessage(ResourceHandler.getValue("INFO_CREATING_FUNC",
//                        rbParameters));
//
//                if (this.offlineMigration) {
//                    this.targetMD.saveScript(this.tddl.getCreateScript(func),
//                            MTKConstants.ObjectTypes.FUNCTION);
//                } else {
//                    this.summary.alertNewFunction(func);
//                    this.targetMD
//                            .executeScript(this.tddl.getCreateScript(func));
//                    this.summary.alertSuccessFunction(func);
//                }
//            } catch (Exception fex) {
//                failureCount += 1;
//                rbParameters = new String[]{func.getName(), fex.getMessage()};
//                logMessage(ResourceHandler.getValue(
//                                "ERR_CREATING_FUNC_WITH_MSG", rbParameters),
//                        Level.ERROR);
//                //mod by kevin 2015年04月28日16:02:54
//                logMessage("Function 原始sql 如下：");
//                logMessage(func.getSQL());
//                logMessage("Function 转换后 sql 如下：");
//                logMessage(this.tddl.getCreateScript(func));
//            }
            Utility.appendFile("function_sql.sql", func.getSQL() + " \n");
        }
    }

    public void copyFunctions(String[] functionNames) throws SQLException {
        String commaSepFunctionNames = getCommaSepObjectNames(functionNames);

        if (commaSepFunctionNames != null) {
            this.sourceMD.getFunctions(commaSepFunctionNames);
        } else {
            this.sourceMD.getAllFunctions();
        }
        try {
            copyFunctions(this.sourceMD.getSchema().getFunctions());
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_FUNC",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copyRules(RuleList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            Rule rule = list.get(i);
            try {
                rbParameters = new String[]{rule.getName()};
                logMessage(ResourceHandler.getValue("INFO_CREATING_RULE",
                        rbParameters));
                if (this.offlineMigration) {
                    this.targetMD.saveScript(this.tddl.getCreateScript(rule),
                            MTKConstants.ObjectTypes.RULE);
                } else {
                    this.summary.alertNewRule(rule);
                    this.targetMD
                            .executeScript(this.tddl.getCreateScript(rule));
                    this.summary.alertSuccessRule(rule);
                }
            } catch (Exception fex) {
                failureCount += 1;
                rbParameters = new String[]{rule.getName(), fex.getMessage()};
                logMessage(ResourceHandler.getValue("ERR_CREATING_RULE",
                        rbParameters), Level.ERROR);
            }
        }
    }

    public void copyRules(String[] ruleNames) throws SQLException {
        String commaSepRuleNames = getCommaSepObjectNames(ruleNames);

        if (commaSepRuleNames != null) {
            this.sourceMD.getRules(commaSepRuleNames);
        } else {
            this.sourceMD.getAllRules();
        }
        try {
            copyRules(this.sourceMD.getSchema().getRules());
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_RULE",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copyGroups(GroupList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            Group group = list.get(i);
            try {
                rbParameters = new String[]{group.getName()};
                logMessage(ResourceHandler.getValue("INFO_CREATING_GROUP",
                        rbParameters));
                if (this.offlineMigration) {
                    this.targetMD.saveScript(this.tddl.getCreateScript(group),
                            MTKConstants.ObjectTypes.GROUP);
                } else {
                    this.summary.alertNewGroup(group);
                    this.targetMD.executeScript(this.tddl
                            .getCreateScript(group));
                    this.summary.alertSuccessGroup(group);
                }
            } catch (Exception fex) {
                failureCount += 1;
                rbParameters = new String[]{group.getName(), fex.getMessage()};
                logMessage(ResourceHandler.getValue("ERR_CREATING_GROUP",
                        rbParameters), Level.ERROR);
            }

        }

        if (((this.sourceDBType == MTKConstants.DATABASE_TYPE.SRDB) || (this.sourceDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB))
                && ((this.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) || (this.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB))) {
            SRDBTransformDDL pgTddl = (SRDBTransformDDL) this.tddl;

            for (int i = 0; i < list.size(); i++) {
                Group group = list.get(i);

                if (!this.summary.hasSuccessStatus("Group", group)) {
                    continue;
                }
                try {
                    rbParameters = new String[]{group.getName()};
                    logMessage(ResourceHandler.getValue(
                            "INFO_CREATING_GROUP_MEMBERSHIP", rbParameters));
                    String groupMembershipScript = pgTddl
                            .getMembershipScript(group);

                    if (groupMembershipScript.equals("")) {
                        continue;
                    }
                    if (this.offlineMigration) {
                        this.targetMD.saveScript(groupMembershipScript,
                                MTKConstants.ObjectTypes.GROUP);
                    } else {
                        this.summary.alertFail("Group", group);
                        this.targetMD.executeScript(groupMembershipScript);
                        this.summary.alertSuccessGroup(group);
                    }
                } catch (Exception fex) {
                    failureCount += 1;
                    rbParameters = new String[]{group.getName(),
                            fex.getMessage()};
                    logMessage(ResourceHandler.getValue(
                                    "ERR_CREATING_GROUP_MEMBERSHIP", rbParameters),
                            Level.ERROR);
                }
            }
        }
    }

    public void copyGroups(String[] groupNames) throws SQLException {
        String commaSepGroupNames = getCommaSepObjectNames(groupNames);

        if (commaSepGroupNames != null) {
            this.sourceMD.getGroups(commaSepGroupNames);
        } else {
            this.sourceMD.getAllGroups();
        }
        try {
            copyGroups(this.sourceMD.getSchema().getGroups());
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_GROUP",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copyDomains(DomainList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            Domain domain = list.get(i);
            try {
                rbParameters = new String[]{domain.getName()};
                logMessage(ResourceHandler.getValue("INFO_CREATING_DOMAIN",
                        rbParameters));
                if (this.offlineMigration) {
                    this.targetMD.saveScript(this.tddl.getCreateScript(domain),
                            MTKConstants.ObjectTypes.DOMAIN);
                } else {
                    this.summary.alertNewDomain(domain);
                    this.targetMD.executeScript(this.tddl
                            .getCreateScript(domain));
                    this.targetConn.commit();
                    this.summary.alertSuccessDomain(domain);
                }

            } catch (Exception fex) {
                if ((this.flagGenStats)
                        && ((fex instanceof SQLException))
                        && (((SQLException) fex).getSQLState()
                        .equalsIgnoreCase("42710"))) {
                    this.summary.alertSuccessDomain(domain);
                } else {
                    failureCount += 1;
                    rbParameters = new String[]{domain.getName(),
                            fex.getMessage()};
                    logMessage(ResourceHandler.getValue("ERR_CREATING_DOMAIN",
                            rbParameters), Level.ERROR);
                }
            }
        }
    }

    public void copyDomains(String[] domainNames) throws SQLException {
        String commaSepDomainNames = getCommaSepObjectNames(domainNames);

        if (commaSepDomainNames != null) {
            this.sourceMD.getDomains(commaSepDomainNames);
        } else {
            this.sourceMD.getAllDomains();
        }
        try {
            copyDomains(this.sourceMD.getSchema().getDomains());
        } catch (Exception ex) {
            rbParameters = new String[]{ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_CUSTOM_TYPE",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copyCustomTypes(DataTypeList list) throws SQLException {
        if ((list == null) || (list.size() == 0))
            return;
        for (int i = 0; i < list.size(); i++) {
            DataType type = list.get(i);
            String typeDDLScript = this.tddl.getCreateScript(type);
            try {
                rbParameters = new String[]{type.getName()};
                logMessage(ResourceHandler.getValue(
                        "INFO_CREATING_CUSTOM_TYPE", rbParameters));
                if (this.offlineMigration) {
                    this.targetMD.saveScript(typeDDLScript,
                            MTKConstants.ObjectTypes.DATATYPE);
                } else {
                    this.summary.alertNewType(type);
                    this.targetMD.executeScript(typeDDLScript);
                    this.targetConn.commit();
                    this.summary.alertSuccessType(type);
                }

            } catch (Exception fex) {
                if ((this.flagGenStats)
                        && ((fex instanceof SQLException))
                        && ((((SQLException) fex).getSQLState()
                        .equalsIgnoreCase("42P07")) || (((SQLException) fex)
                        .getSQLState().equalsIgnoreCase("42710")))) {
                    this.summary.alertSuccessType(type);
                } else {
                    failureCount += 1;
                    rbParameters = new String[]{type.getName(),
                            fex.getMessage()};
                    logMessage(ResourceHandler.getValue(
                                    "ERR_CREATING_CUSTOM_TYPE", rbParameters),
                            Level.ERROR);
                }
            }
        }
    }

    public void copyCustomTypes(String[] typeNames) throws SQLException {
        String commaSepTypeNames = getCommaSepObjectNames(typeNames);

        if (commaSepTypeNames != null) {
            this.sourceMD.getCustomDataTypes(commaSepTypeNames);
        } else {
            this.sourceMD.getAllCustomDataTypes();
        }
        try {
            copyCustomTypes(this.sourceMD.getSchema().getCustomTypes());
        } catch (Exception ex) {
            rbParameters = new String[]{"", ex.getMessage()};
            logMessage(ResourceHandler.getValue("ERR_CREATING_DOMAIN",
                    rbParameters));
            throw new SQLException(ex.getMessage());
        }
    }

    public void copyDBLinks() throws SQLException {
        this.sourceMD.getAllDBLinks();
        String[] passwordValues = null;
        if (dblinkPasswords != null) {
            passwordValues = dblinkPasswords.split(",");
        }
        DBLinkList list = this.sourceMD.getSchema().getDBLinks();
        for (int i = 0; i < list.size(); i++) {
            DBLink link = list.get(i);
            try {
                if ((!link.isValidHost())
                        || (link.getUserName() == null)
                        || (link.getUserName().equals(""))
                        || (link.getUserName().equalsIgnoreCase("current_user"))) {
                    logMessage(ResourceHandler.getValue("WRN_DBLINK_MSG",
                            new String[]{link.getName()}));
                } else {
                    rbParameters = new String[]{link.getName()};
                    logMessage(ResourceHandler.getValue(
                            "INFO_CREATING_DBLINLK", rbParameters));

                    if (passwordValues != null) {
                        String password = Utility.hasDBlinkPasswords(
                                passwordValues, link.getName());

                        if (password != null) {
                            link.setPassword(password);
                        }
                    }

                    if (this.offlineMigration) {
                        this.targetMD.saveScript(
                                this.tddl.getCreateScript(link),
                                MTKConstants.ObjectTypes.DBLINK);
                    } else {
                        this.summary.alertNewDBLinks(link);
                        this.targetMD.executeScript(this.tddl
                                .getCreateScript(link));
                        this.summary.alertSuccessDBLink(link);
                    }
                }
            } catch (Exception pex) {
                failureCount += 1;
                rbParameters = new String[]{link.getName(), pex.getMessage()};
                logMessage(ResourceHandler.getValue(
                                "ERR_CREATING_DBLINK_WITH_MSG", rbParameters),
                        Level.ERROR);
            }
        }
    }

    public void copyObjectTypes() throws SQLException {
        this.sourceMD.getAllObjectTypes();
        ObjectTypeList objTypelist = this.sourceMD.getSchema().getObjectTypes();

        for (int i = 0; i < objTypelist.size(); i++) {
            ObjectType objType = objTypelist.get(i);
            rbParameters = new String[]{objType.getName()};
            logMessage(ResourceHandler.getValue("INFO_CREATING_OBJECTTYPE",
                    rbParameters));
            try {
                if (this.offlineMigration) {
                    this.targetMD.saveScript(
                            this.tddl.getCreateScript(objType),
                            MTKConstants.ObjectTypes.OBJECTTYPE);
                } else {
                    this.summary.alertNewObjectType(objType);
                    this.targetMD.executeScript(this.tddl
                            .getCreateScript(objType));
                    this.summary.alertSuccessObjectType(objType);
                }
            } catch (Exception ex) {
                failureCount += 1;
                rbParameters = new String[]{objType.getName(),
                        ex.getMessage()};
                logMessage(ResourceHandler.getValue(
                                "ERR_CREATING_OBJECTTYPE_WITH_MSG", rbParameters),
                        Level.ERROR);
            }
        }
    }

    private String getCommaSepObjectNames(String[] schemaObjectNames) {
        StringBuffer commaSepObjectNames = new StringBuffer();

        if (schemaObjectNames != null) {
            String schemaObjectName = null;
            for (int i = 0; i < schemaObjectNames.length; i++) {
                schemaObjectName = schemaObjectNames[i];

                schemaObjectName = schemaObjectName.replaceAll("'", "''");

                if (i > 0) {
                    commaSepObjectNames.append(",");
                }

                commaSepObjectNames.append("'").append(schemaObjectName)
                        .append("'");
            }
        } else {
            return null;
        }

        return commaSepObjectNames.toString();
    }

    protected void disableTableContraints(String tableName) throws SQLException {
        disableTableContraints(tableName, this.targetMD);
    }

    protected synchronized void disableTableContraints(String tableName,
                                                       MTKMetaData targetMD) throws SQLException {
        if ((this.targetDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                || (this.targetDBType == MTKConstants.DATABASE_TYPE.NPS)) {
            return;
        }
        rbParameters = new String[]{tableName};
        logMessage(ResourceHandler.getValue(
                "INFO_DISABLING_FK_CONSTR_TRIGGER_INDEXES_BEFORE_TRUNC",
                rbParameters));

        if (this.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER) {
            targetMD.executeScript("ALTER TABLE " + tableName
                    + " NOCHECK CONSTRAINT ALL");
        } else if (((targetMD.getDBServerMajorVersion() == 8) && (targetMD
                .getDBServerMinorVersion() >= 4))
                || (targetMD.getDBServerMajorVersion() > 8)) {
            targetMD.executeScript("Update sr_catalog.sr_class set relhastriggers = false where oid = '"
                    + tableName + "'::sr_catalog.regclass");
        } else
            targetMD.executeScript("Update sr_catalog.sr_class set reltriggers = 0 where oid = '"
                    + tableName + "'::sr_catalog.regclass");
    }

    protected void disableTableIndexes(String tableName) throws SQLException {
        disableTableIndexes(tableName, this.targetMD);
    }

    protected synchronized void disableTableIndexes(String tableName,
                                                    MTKMetaData targetMD) throws SQLException {
        if ((this.targetDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                || (this.targetDBType == MTKConstants.DATABASE_TYPE.NPS)
                || (this.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)) {
            return;
        }

        rbParameters = new String[]{tableName};
        logMessage(ResourceHandler.getValue(
                "INFO_DISABLING_INDEXES_BEFORE_DATA_LOAD", rbParameters));

        targetMD.executeScript("update sr_catalog.sr_class set relhasindex = 'f' where oid = '"
                + tableName + "'::sr_catalog.regclass");
    }

    protected void dropTableConstsAndIndexes(Table table) throws SQLException {
        dropTableConstsAndIndexes(table, this.targetMD);
    }

    protected synchronized void dropTableConstsAndIndexes(Table table,
                                                          MTKMetaData targetMD) throws SQLException {
        rbParameters = new String[]{table.getTargetSchemaFullyQualifiedName(
                this.sourceDBType, this.targetDBType, false)};
        logMessage(ResourceHandler.getValue(
                "INFO_DISABLING_INDEXES_BEFORE_DATA_LOAD", rbParameters));

        targetMD.dropTableConstsAndIndexes(this.sourceDBType, table);
    }

    protected void enableTableContraints(String tableName) throws SQLException {
        enableTableContraints(tableName, this.targetMD);
    }

    protected synchronized void enableTableContraints(String tableName,
                                                      MTKMetaData targetMD) throws SQLException {
        if ((this.targetDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                || (this.targetDBType == MTKConstants.DATABASE_TYPE.NPS)) {
            return;
        }

        rbParameters = new String[]{tableName};
        logMessage(ResourceHandler.getValue(
                "INFO_ENABLING_FK_CONSTR_TRIGGER_INDEXES_BEFORE_TRUNC",
                rbParameters));

        if (this.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER) {
            targetMD.executeScript("ALTER TABLE " + tableName
                    + " CHECK CONSTRAINT ALL");
        } else if (((targetMD.getDBServerMajorVersion() == 8) && (targetMD
                .getDBServerMinorVersion() >= 4))
                || (targetMD.getDBServerMajorVersion() > 8)) {
            targetMD.executeScript("Update sr_catalog.sr_class  set relhastriggers = case when (select sr_catalog.count(*) FROM sr_catalog.sr_trigger where sr_class.oid = tgrelid) > 0 then true else false end where oid = '"
                    + tableName + "'::sr_catalog.regclass");
        } else {
            targetMD.executeScript("Update sr_catalog.sr_class  set reltriggers = (select sr_catalog.count(*) FROM sr_catalog.sr_trigger where sr_class.oid = tgrelid) where oid = '"
                    + tableName + "'::sr_catalog.regclass");
        }
    }

    protected void enableTableIndexes(String tableName) throws SQLException {
        enableTableIndexes(tableName, this.targetMD);
    }

    protected void enableTableIndexes(String tableName, MTKMetaData targetMD)
            throws SQLException {
        if ((this.targetDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                || (this.targetDBType == MTKConstants.DATABASE_TYPE.NPS)
                || (this.targetDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)) {
            return;
        }

        rbParameters = new String[]{tableName};
        logMessage(ResourceHandler.getValue(
                "INFO_ENABLING_INDEXES_AFTER_DATA_LOAD", rbParameters));
        targetMD.executeScript("update sr_catalog.sr_class set relhasindex = 't' where oid in (select indrelid from sr_catalog.sr_index where indrelid =  '"
                + tableName + "'::sr_catalog.regclass)");

        if (tableName.contains("''")) {
            tableName = tableName.replace("''", "'");
        }

        targetMD.executeScript("reindex table " + tableName);
    }

    protected void restoreTableConstsAndIndexes(Table table)
            throws SQLException {
        restoreTableConstsAndIndexes(table, this.sourceMD, this.targetMD);
    }

    protected void restoreTableConstsAndIndexes(Table table,
                                                MTKMetaData sourceMD, MTKMetaData targetMD) throws SQLException {
        rbParameters = new String[]{table.getTargetSchemaFullyQualifiedName(
                this.sourceDBType, this.targetDBType, false)};
        logMessage(ResourceHandler.getValue(
                "INFO_ENABLING_INDEXES_AFTER_DATA_LOAD", rbParameters));

        if (this.replicationMode.equalsIgnoreCase("S")) {
            this.flagSkipFKConst = true;
        }

        this.flagSkipCKConst = (!table.isHasCheckConst());
        sourceMD.clearConstraintsList();
        sourceMD.clearIndexesList();

        copyConstraints(
                new String[]{Utility.removeEnclosingQuotes(table.getName())},
                sourceMD, targetMD);

        if ((this.sourceDBType == MTKConstants.DATABASE_TYPE.SQLSERVER)
                && ((this.targetDBType == MTKConstants.DATABASE_TYPE.SRDB) || (this.targetDBType == MTKConstants.DATABASE_TYPE.ENTERPRISEDB))) {
            ArrayList<String> indexList = targetMD.getListTableIndexesDefs();
            for (String indexSQL : indexList)
                targetMD.executeScript(indexSQL);
        } else {
            copyIndexes(new String[]{Utility.removeEnclosingQuotes(table
                    .getName())}, sourceMD, targetMD);
        }
    }

    private static boolean isEscapeCharacter(String input) {
        if ((input != null) && (input.length() == 3)
                && (input.startsWith("\\\\"))) {
            char character = input.charAt(2);
            switch (character) {
                case 'b':
                case 'f':
                case 'n':
                case 'r':
                case 't':
                    return true;
            }
            return false;
        }
        if ((input != null) && (input.length() == 2)
                && (input.startsWith("\\"))) {
            char character = input.charAt(1);
            switch (character) {
                case '"':
                case '\'':
                case '\\':
                    return true;
            }
            return false;
        }

        return false;
    }

    private static char escapeCharacter(String input) {
        if ((input != null) && (input.length() == 3)
                && (input.startsWith("\\\\"))) {
            char character = input.charAt(2);
            switch (character) {
                case 't':
                    return '\t';
                case 'b':
                    return '\b';
                case 'n':
                    return '\n';
                case 'r':
                    return '\r';
                case 'f':
                    return '\f';
            }
        } else if ((input != null) && (input.length() == 2)
                && (input.startsWith("\\"))) {
            char character = input.charAt(1);
            switch (character) {
                case '\'':
                    return '\'';
                case '"':
                    return '"';
                case '\\':
                    return '\\';
            }
        }
        return '\t';
    }

    public static synchronized void incrementFailureCount() {
        failureCount += 1;
    }

    public void summaryAlert(String type, DBObject obj, boolean successStatus) {
        if (successStatus)
            this.summary.alertSuccess(type, obj);
        else
            this.summary.alertFail(type, obj);
    }

    public void setFlagUserSpecifiedTargetSchemaName(
            boolean flagUserSpecifiedTargetSchemaName) {
        this.flagUserSpecifiedTargetSchemaName = flagUserSpecifiedTargetSchemaName;
    }

    public static boolean skipColDefaultClause() {
        return skipColDefaultClause;
    }

    public static boolean replaceNullChar() {
        return replaceNullChar;
    }

    public static char nullReplacementChar() {
        return nullReplacementChar;
    }

    public static Hashtable getNZOptions() {
        return nzOptions;
    }

    protected static String getNZOptionValue(String optName) {
        Enumeration keys = nzOptions.keys();
        while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            if (key.equalsIgnoreCase(optName)) {
                return (String) nzOptions.get(key);
            }
        }

        return null;
    }

    public static boolean isMemberOfPartitionTableList(Table table) {
        if (importPartitionAsTable) {
            if (partitionTableList == null) {
                return table.isPartitioned();
            }
            for (String partitionTable : partitionTableList) {
                if (partitionTable.equals(table.getName())) {
                    return true;
                }
            }

        }

        return false;
    }

    public void resetSummary() {
        this.summary.resetList();
    }

    public IMTKConnection getSrcConn() {
        return this.srcConn;
    }

    public IMTKConnection getTargetConn() {
        return this.targetConn;
    }

    protected IMTKConnection createNewSourceConnection() throws MTKException {
        if ((this.sourceDBType == MTKConstants.DATABASE_TYPE.ORACLE)
                && (Utility.isCaseSensitive(this.sourceSchema,
                this.sourceDBType))) {
            return this.mtkFactory.createMTKConnection(this.sourceDBType,
                    this.srcDBURL, "\"" + this.srcDBUser + "\"",
                    this.srcDBPassword);
        }
        return this.mtkFactory.createMTKConnection(this.sourceDBType,
                this.srcDBURL, this.srcDBUser, this.srcDBPassword);
    }

    protected IMTKConnection createNewTargetConnection() throws MTKException {
        return this.mtkFactory.createMTKConnection(this.targetDBType,
                this.targetDBURL, this.targetDBUser, this.targetDBPassword);
    }

    protected MTKMetaData createSourceMetaData(IMTKConnection conn)
            throws MTKException {
        return this.mtkFactory
                .createMTKMetaData(this.sourceDBType, conn,
                        Utility.isCaseSensitive(this.targetSchema,
                                this.targetDBType) ? "\"" + this.targetSchema
                                + "\"" : this.targetSchema);
    }

    protected MTKMetaData createTargetMetaData(IMTKConnection conn)
            throws MTKException {
        return this.mtkFactory
                .createMTKMetaData(this.targetDBType, conn,
                        Utility.isCaseSensitive(this.targetSchema,
                                this.targetDBType) ? "\"" + this.targetSchema
                                + "\"" : this.targetSchema);
    }

    protected void connectDBLinkOra(MTKData targetData) throws SQLException {
        ((Data) targetData).connectDBlinkOra(this.srcDBURL, this.srcDBUser,
                this.srcDBPassword);
    }

    public boolean useSingleDataFile() {
        return this.useSingleDataFile;
    }

    public boolean offlineMigration() {
        return this.offlineMigration;
    }

    /**
     * 增加迁移表数目,Dataloader类每成功迁移一张表,调用一次
     */
    public void addMigratedTables() {
        migratedTables++;
        iuiOperation.infoProgress(getMigrationProcess());
//        System.out.println("MigrationToolkit6019" + migratedTables);
    }

    private void addMigratedIndex() {
        migratedIndexes++;
        iuiOperation.infoProgress(getMigrationProcess());
    }

    private void addMigratedConstraints() {
        migratedConstraints++;
        iuiOperation.infoProgress(getMigrationProcess());
    }

    private void addMigratedViews() {
        migratedViews++;
        iuiOperation.infoProgress(getMigrationProcess());
    }

    /**
     * 获取迁移进度
     * 默认迁移表占比20%,迁移索引占比20%,迁移约束占比20%,迁移视图占比20%,其它迁移操作占比20%
     *
     * @return 迁移进度百分比
     */
    public static double getMigrationProcess() {
        return getOwnProcess(tableNum, migratedTables, migrateTableFlag) * 20 +
                getOwnProcess(indexNum, migratedIndexes, migrateIndexFlag) * 20 +
                getOwnProcess(constraintsNum, migratedConstraints, migrateConstraintsFlag) * 20 +
                getOwnProcess(viewNum, migratedViews, migrateViewFlag) * 20 +
                (migrateFlag ? 1 : 0) * 20;
    }

    /**
     * 获取分项迁移进程
     *
     * @param totalNum    需要迁移的数目
     * @param migratedNum 已经迁移的数目
     * @param flag        表示是否已经执行迁移操作
     * @return 分项迁移进度
     */
    private static double getOwnProcess(int totalNum, int migratedNum, boolean flag) {
        if (flag) {
            return 1;
        } else {
            if (totalNum == 0)
                return 0;
            else {
                return (double) migratedNum / (double) totalNum;
            }
        }
    }
}
